DP1

View Code
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 const int MAX = 1000;
 7 int N, w[MAX], v[MAX], sum[MAX*MAX],i,num,n,j;
 8 int main()
 9 {
10     while(~scanf("%d%d",&num,&n))
11     {
12         memset(sum, 0, sizeof(sum));
13         for(i=1; i<=n; i++) scanf("%d%d",&w[i], &v[i]);
14         for(i=1; i<=n; i++)
15             for(j=num; j>=w[i]; j--)
16                 sum[j] = max(sum[j], sum[j-w[i]] + v[i]);// 包括或不包括第i个物品,比较总价值大小,sum[j]表示体积为j时的最大价值
17         printf("%d\n", sum[num]);
18     }
19     return 0;
20 }
View Code

杭电2602

 1 #include <iostream>
 2 using namespace std;
 3 struct commodity
 4 {
 5     int value; 
 6     int weight; 
 7 };
 8 int select[1001][1001];
 9 commodity goods[1001]={{0,0}};
10 
11 int max_value(int N, int W,commodity goods[]);
12 
13 int main()
14 {
15     int N, W, T, i;
16     cin >> T;
17     while(T--)
18     {        
19         cin >> N >> W;
20         for(i = 1; i < N + 1; i++)
21             cin >> goods[i].value;
22         for(i = 1; i < N + 1; i++)
23             cin >> goods[i].weight;        
24         cout<<max_value(N, W, goods)<<endl;
25     }
26     return 0;
27 }
28 int max_value(int N, int W,commodity goods[])
29 {
30                                                                                  //首先是定义一个状态
31     for(int i=1;i<=N;++i)
32     {
33         select[i][0] = 0;  //背包容量为0时,最大价值为0
34         for(int w=0;w<=W;++w)
35         {
36             if(goods[i].weight <= w)  //当前物品i的重量小于等于w,进行选择
37             {
38                 if( (goods[i].value + select[i-1][w-goods[i].weight]) > select[i-1][w])                        //状态转移方程
39                     //DP[i][j] Weight不超过j的时候   不选i+1     选i+1
40                     //DP[i+1][j]=max{DP[i][j],DP[i][j-W[i]]+V[i]} 
41                     select[i][w] = goods[i].value + select[i-1][w-goods[i].weight];            //描述状态转移的过程
42                 else
43                     select[i][w] = select[i-1][w];
44             }
45             else //当前物品i的重量大于w,不选择
46                 select[i][w] = select[i-1][w];
47         }
48     }
49     return select[N][W];  //最终求得最大值
50 }
51 // 将两处循环中的w改为0,可以对
View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 int max(int x,int y)
 4 {
 5  return x>y?x:y;
 6 }
 7  int N,a[1002],b[1002],c[1002],i,m,n,j;
 8 
 9 int main()
10 {
11  scanf("%d",&N);
12  while(N--)
13  {
14    memset(c,0,sizeof(c));
15 
16   scanf("%d%d",&n,&m);
17   for(i=1;i<=n;i++) scanf("%d",&a[i]);
18   for(i=1;i<=n;i++) scanf("%d",&b[i]);
19   for(i=1;i<=n;i++)
20    for(j=m;j>=b[i];j--)                    //  c若为二维,会有很大的浪费,可以用一维的,只是 j 的初始值应为最大体积m
21     c[j]=max(c[j],c[j-b[i]]+a[i]);                // 包括或不包括第i个物品,比较总价值大小,c[j]表示体积为j时的最大价值
22    printf("%d\n",c[m]);
23  }
24  return 0;
25 }
View Code

一方法不太好,二方法减少二维数组的浪费,同时意思更容易理解

 

01背包的状态转移方程为:dp[i][v]=max(dp[i-1][v],dp[i-1][v-vi[i]]+va[i]);

而要储存起前K种情况就需要将状态方程转化为:dp[i-1][v]=>dp[i-1][v][1……k],dp[i-1][v-vi[i]]+va[i]=>dp[i-1][v-vi[i]][1……k]+va[i];

posted @ 2015-04-07 18:18  PastLIFE  阅读(211)  评论(0编辑  收藏  举报