http://acm.hdu.edu.cn/showproblem.php?pid=1712
2 2 1 2 1 3 2 2 2 1 2 1 2 3 3 2 1 3 2 1 0 0
3 4 6
这题可以用分组背包来做,把每个工作看成一组物品,把花费x天能获得的价值看成该组物品的其中一个商品,在这组物品里面最多只能选一个物品。这个题还可以从另一个角度来思考,我们可以把每个工作看成背包九讲里面提到的泛化物品。所谓泛化物品即一个物品,不同的花费对应不同的价值。用数组来表示泛化物品:h[0....v],不同的花费对应不同的价值。
两个泛化物品可以合并成一个泛化物品。假设我们已知两个泛化物品h[v]和l[v],设他们合成后的泛化物品为f[v],则f[k]=max(h[i]+l[k-i]),0=<i<=k。
所以这个题我们可以把N个泛化物品合并成一个泛化物品,就可以求出答案,复杂度O(n^3)。代码如下:
#include<stdio.h> #include<iostream> #include<string> #include<string.h> #include<vector> #include<algorithm> #define nn 1100 #define inff 0x3fffffff #define mod 1000000007 using namespace std; typedef long long LL; int n,m; int a[nn][nn]; int f[nn][nn]; int main() { int i,j,k; while(scanf("%d%d",&n,&m)) { if(n==0&&m==0) break; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%d",&a[i][j]); } } memset(f,0,sizeof(f)); for(i=1;i<=n;i++) { for(j=0;j<=m;j++) { for(k=0;k<=j;k++) { f[i][j]=max(f[i][j],f[i-1][k]+a[i][j-k]);//前i-1个泛化物品合成的泛化物品与第i个泛化物品合并 } } } printf("%d\n",f[n][m]); } return 0; }