|
沙发
楼主 |
发表于 2021-10-14 14:47:10
|
只看该作者
fi,j,k表示走到(i,j)、背包剩余容量为k时的最大价值。
fi,j由fi-1,j和fi,j-1按普通01背包的方法转移。
时间复杂度O(N2V),空间O(N2V)。
按行或对角线滚动数组,空间O(NV)。
- #include<iostream>
- #include<cstdio>
- #define FOR(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int N=500,INF=1000010000;
- int n,m,ans,c[N][N],w[N][N],S,f[2][N][N];
- int main()
- {
- freopen("matrix.in","r",stdin);
- freopen("matrix.out","w",stdout);
- scanf("%d%d%d",&n,&m,&S);
- FOR(i,1,n)FOR(j,1,m) scanf("%d",&c[i][j]);
- FOR(i,1,n)FOR(j,1,m) scanf("%d",&w[i][j]);
- FOR(i,0,1)FOR(j,0,m)FOR(k,0,S) f[i][j][k]=-INF;
- f[0][1][0]=0;
- FOR(i,1,n)FOR(j,1,m)
- {
- FOR(k,0,S)
- {
- f[i&1][j][k]=max(f[i&1][j-1][k],f[i&1^1][j][k]);
- if(k>=c[i][j])
- {
- f[i&1][j][k]=max(f[i&1][j][k],f[i&1][j-1][k-c[i][j]]+w[i][j]);
- f[i&1][j][k]=max(f[i&1][j][k],f[i&1^1][j][k-c[i][j]]+w[i][j]);
- }
- if(f[i&1][j][k]<0) f[i&1][j][k]=-INF;
- }
- //cout<<i<<' '<<j<<endl;
- //FOR(k,0,S) cout<<f[i&1][j][k]<<' ';cout<<endl;
- }
- FOR(k,1,S) ans=max(ans,f[n&1][m][k]);
- printf("%d",ans);
- }/*
- 3 3 2
- 0 1 1
- 1 1 2
- 2 1 0
- 0 2 4
- 2 3 4
- 4 3 0
- */
复制代码
|
|