标签:
背包问题
01背包
1. 问题描述 http://hihocoder.com/problemset/problem/1038
有M张奖券,奖品区有N件奖品,分别标号为1到N,其中第i件奖品需要need(i)张奖券进行兑换且评分值为value(i)。每件奖品最多只能兑换一次。凭借他手上的M张奖券,可以换到哪些奖品,使得这些奖品的喜好值之和能够最大。
奖品标号 | 1 | ... | i | ... | N |
需要奖券 | need(1) | ... | need(i) | ... | need(N) |
评分值 | value(1) | ... | value(i) | ... | value(N) |
2. 状态转换
3. 代码
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<stdio.h> 4 int dp[505][100005]; 5 int w[505],v[505]; 6 int max(int m,int n) 7 { 8 return m>n?m:n; 9 } 10 void solve(int n,int m) 11 { 12 int i,j; 13 for(i=0;i<=m;i++) 14 dp[0][i]=0; 15 for(i=0; i<n; i++) 16 for(j=0; j<=m; j++) 17 { 18 if(j<w[i]) 19 dp[i+1][j]=dp[i][j]; 20 else 21 dp[i+1][j]=max(dp[i][j],dp[i][j-w[i]]+v[i]); 22 } 23 printf("%d",dp[n][m]); 24 } 25 int main() 26 { 27 int n,m,i; 28 scanf("%d%d",&n,&m); 29 for(i=0;i<n;i++) 30 scanf("%d%d",&w[i],&v[i]); 31 solve(n,m); 32 return 0; 33 }
完全背包
1. 问题描述 http://hihocoder.com/problemset/problem/1043
可以兑换无数次
2. 状态转换
3. 代码
1 #include <iostream> 2 using namespace std; 3 const int maxN = 501; 4 const int maxM = 100001; 5 int values[maxN][maxM]; 6 struct Prize 7 { 8 int need; 9 int value; 10 }prizes[maxN]; 11 12 13 void dp(int N, int M) 14 { 15 for (int i = 0; i <= M; i++) 16 if (i >= prizes[0].need) 17 values[0][i] = i / prizes[0].need * prizes[0].value; 18 else 19 values[0][i] = 0; 20 int max = 0; 21 for (int i = 1; i < N; i++) 22 { 23 for (int j = 0; j <= M; j++) 24 { 25 if (prizes[i].need > j) 26 values[i][j] = values[i - 1][j]; 27 else 28 { 29 int tmp = values[i][j - prizes[i].need] + prizes[i].value; 30 if (tmp > values[i - 1][j]) 31 values[i][j] = tmp; 32 else 33 values[i][j] = values[i - 1][j]; 34 } 35 } 36 } 37 } 38 39 int main() 40 { 41 int M, N; 42 cin >> N >> M; 43 for (int i = 0; i < N; i++) 44 cin >> prizes[i].need >> prizes[i].value; 45 prizes[N].need = prizes[N].value = 0; 46 47 dp(N, M); 48 cout << values[N - 1][M] << endl; 49 return 0; 50 }
标签:
原文地址:http://www.cnblogs.com/coolqiyu/p/5960565.html