HDU - 1712 - ACboy needs your help
先上题目:
ACboy needs your help
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3464 Accepted Submission(s): 1792
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.
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天,不同的课花不同的时间在里面会有不同的价值,问最大价值是多少?
分组背包,状态转移方程dp[k][v]=max{dp[k-1][v],dp[k-1][v-c[k][i]]+w[k][i]} c[k][i],w[k][i]分别代表第k组物品的i个物品的代价和价值。
需要注意的问题是,枚举背包容量和每一个分组里面的物品的时候,最外面一层循环枚举组数,中间一层应该是枚举背包容量,里面一层枚举某一个分组里面的物品,为什么要这样,因为如果中间一层和最里面的一层如果交换了位置的话,那就不是01背包了,同一组里面的物品被多次枚举,而原本同一组里面的物品需要互斥,所以最里面一层枚举某一个分组里面的物品,这样的话因为枚举背包容量的时候是从大到小枚举的,所以对于同一个背包容量,某一组的物品只会放进去一次,这样就保证互斥了。
上代码:
1 #include <cstdio> 2 #include <cstring> 3 #define max(x,y) (x > y ? x : y) 4 #define MAX 102 5 using namespace std; 6 7 int a[MAX][MAX]; 8 int dp[MAX]; 9 10 int main() 11 { 12 int n,m,maxn; 13 //freopen("data.txt","r",stdin); 14 while(scanf("%d %d",&n,&m),(n+m)){ 15 memset(a,0,sizeof(a)); 16 memset(dp,0,sizeof(dp)); 17 for(int i=1;i<=n;i++){ 18 for(int j=1;j<=m;j++){ 19 scanf("%d",&a[i][j]); 20 } 21 } 22 maxn=0; 23 for(int i=1;i<=n;i++){ 24 for(int k=m;k>=1;k--){ 25 for(int j=1;j<=k;j++){ 26 dp[k]=max(dp[k],dp[k-j]+a[i][j]); 27 maxn=max(dp[k],maxn); 28 } 29 } 30 } 31 printf("%d\n",maxn); 32 } 33 return 0; 34 }