中间一度怀疑是牛客的测评机出问题了……才发现是自己的数组越界。
太艰难了。
https://ac.nowcoder.com/acm/contest/2340/C
题目是比较简单的,思路大概就是求解第一天到第t-1天的最佳策略,所以大概也可以说是一道贪心的题目。
那么怎么确定最佳策略呢——填表。每个纪念品都会覆盖到某个值下的最优解,并且可以使得后续可以直接调用其生成的最优解,最后推出m对应的生成价值。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e4+5;
int main() {
    int a[105][105];
    int val[N]= {0};
    int t,n,m;
    cin>>t>>n>>m;
    for(int i=0; i<t; i++)
        for(int j=0; j<n; j++)
            cin>>a[i][j];
    t--;//最后一天直接卖掉 所以不算 我就是这里傻到然后数组越界(讲道理我置零了)(算了无所谓了
    for(int i=0; i<t; i++) {//遍历每一天
        memset(val,0,sizeof(val));
        for(int j=0; j<n; j++)//遍历每一个商品
            for(int k=a[i][j]; k<=m; k++)
                val[k]=max(val[k],a[i+1][j]-a[i][j]+val[k-a[i][j]]);
                //当天可以收割的最高价值
        m+=val[m];
    }
    cout<<m<<endl;
    return 0;
}
for(int k=a[i][j]; k<=m; k++)
                val[k]=max(val[k],a[i+1][j]-a[i][j]+val[k-a[i][j]]);

我总觉得这一块效率太低了,居然是一个一个填进入,而且每一位都要调用一次max函数,总觉得有更优的方案。
这个方案生成了大量的无用数据,如果数据覆盖范围广的话还好说,就只有两三个值的时候很多数据都是无效的。
挖坑again。顺便吐槽马上学校又要开网课了,致命的高数下,而且我下学期课又多,天知道还有没有时间填坑……

有一种绥靖政策的优化:如果明天降价就不考虑了

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
int t,n,m,a[105][105],dp[10005];
int main() {
    int i,j,k;
    cin>>t>>n>>m;
    for(i=1; i<=t; i++) 
        for(j=1; j<=n; j++) 
            scanf("%d",&a[i][j]);
    for(i=1; i<t; i++) {
        memset(dp,0,sizeof(dp));
        for(j=1; j<=n; j++) {
            if(a[i][j]>=a[i+1][j]) continue;
            for(k=a[i][j]; k<=m; k++) 
                dp[k]=max(dp[k],dp[k-a[i][j]]+a[i+1][j]-a[i][j]);
        }
        m=m+dp[m];
    }
    cout<<m;
    return 0;
}

写到这里就越来越觉得是贪心了,那么是怎么解决“放长线钓大鱼”的问题的呢?


画了一下曲线,发现根本不存在“放长线钓大鱼”的问题,贪心永远是对的,因为信息是完全的,晚买永远是没问题的,计算每一天的收益就是最高收益。