HDU 1712 ACboy needs your help(背包)

http://acm.hdu.edu.cn/showproblem.php?pid=1712

ACboy needs your help

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3809    Accepted Submission(s): 1977


Problem Description
ACboy has N courses this term, and he plans to spend at most M days on study.Of course,the profit he will gain from different course depending on the days he spend on it.How to arrange the M days for the N courses to maximize the profit?
 

Input
The input consists of multiple data sets. A data set starts with a line containing two positive integers N and M, N is the number of courses, M is the days ACboy has.
Next follow a matrix A[i][j], (1<=i<=N<=100,1<=j<=M<=100).A[i][j] indicates if ACboy spend j days on ith course he will get profit of value A[i][j].
N = 0 and M = 0 ends the input.
 

Output
For each data set, your program should output a line which contains the number of the max profit ACboy will gain.
 

Sample Input
   
   
   
   
2 2 1 2 1 3 2 2 2 1 2 1 2 3 3 2 1 3 2 1 0 0
 

Sample Output
   
   
   
   
3 4 6
题意:输入N和M,N表示工作个数,M表示用来工作的天数,再给一个N*M的矩阵A,A[i][j]表示第i项工作花费j天获得的价值,求工作M天能求得的最大价值。

这题可以用分组背包来做,把每个工作看成一组物品,把花费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;
}


你可能感兴趣的:(dp,动态规划,ACM,背包)