矩阵 matrix

  传送门 注意这题时限是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 }
View Code
光伴随的阴影
原文地址:https://www.cnblogs.com/forward777/p/10326765.html