传送门 注意这题时限是2s
【问题描述】
有一个n × m的矩阵,你从左上角走到右下角,只能向下和向右走。
每个点上有一个重量v i,j 价值w i,j 的物品,你有一个容量为S的背包,经过一个点你可以
将此点的物品放入背包,求最大能得到的价值。
【输入】
输入文件 matrix.in。
第一行三个数n, m, S。
下面n行,每行m个数,第i + 1行第j个数表示v i,j 。
下面n行,每行m个数,第i + n + 1行第j个数表示w i,j 。
【输出】
输出文件 matrix.out。
一行一个数表示最大的价值。【数据范围】
n, m ≤ 400, 0 ≤ v i,j , w i,j ≤ 1000, S ≤ 400
思路:
直接背包 由上面或者下面的点转移过来就可以了
但是数组要滚动的 不然就MLE了
(好像大家都是f[2][401]401]?我觉得不需要第一维啊)
反思:
一个这样子的题我也只有30分
因为转移取max的时候落掉了f[j-1][k]
而且还有 k : 0~j-1 时没有转移 (写飞扬的小鸟也是这一步出错)
要长记性啦!! 对于一个状态没有转移的情况要想清楚啊
再有把握的题也不要做得太快了 至少还是要再想清楚一遍
1 #include<iostream> 2 #include<cstdio> 3 #define go(i,a,b) for(register int i=a;i<=b;i++) 4 #define yes(i,a,b) for(register int i=a;i>=b;i--) 5 using namespace std; 6 int read() 7 { 8 int x=0,y=1;char c=getchar(); 9 while(c<'0'||c>'9') {if(c=='-') y=-1;c=getchar();} 10 while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();} 11 return x*y; 12 } 13 int n,m,s,ans,v[410][410],w[410][410],f[410][410]; 14 int main() 15 { 16 //freopen("matrix.in","r",stdin); 17 //freopen("matrix.out","w",stdout); 18 n=read();m=read();s=read(); 19 go(i,1,n) go(j,1,m) v[i][j]=read(); 20 go(i,1,n) go(j,1,m) w[i][j]=read(); 21 go(i,1,n) 22 go(j,1,m) 23 { 24 yes(k,s,v[i][j]) 25 { 26 f[j][k]=max(max(max(f[j][k-v[i][j]],f[j-1][k-v[i][j]])+w[i][j],f[j][k]),f[j-1][k]); 27 ans=max(ans,f[j][k]); 28 } 29 go(k,0,v[i][j]-1) f[j][k]=max(f[j][k],f[j-1][k]); 30 } 31 printf("%d",ans); 32 return 0; 33 }