题目链接:http://poj.org/problem?id=3624

 

题意:一共给出n种手镯,每个手镯有着各自的重量以及魅力值,在m重量下能得到的最大魅力值是多少。

分析:标准的01背包。状态转移如此:

dp[i][j]表示前i个手镯在重量为j的背包容量下能达到的最大魅力值。w[i]是第i个手镯的重量,d[i]是第i个手镯的魅力值。

如果某个超过背包重量,则一定不放入背包。问题则为剩余i-1个手镯装入重量的容量为j的背包得到的最大魅力值。

否则该手镯放入背包。问题则为剩余i-1个手镯装入重量的容量为j-w[i]的背包能到的的最大价值加上手镯i的价值d[i]。

if (w[i]>j) dp[i][j] = dp[i-1][j]

else dp[i][j] = max(dp[i-1][j-w[i]]+d[i],dp[i-1][j])

第一次用二维写的,,,好吧,貌似只能用一维这题

手工模拟一下发现dp[i,j]只跟之前的某几个值有关,再之前计算的结果就都没用了...
所以我们就可以用一个数组来重复使用了,不过要倒序,保证无后效性...

 

Sample Input

4 6
1 4
2 6
3 12
2 7
Sample Output

23

 

AC代码:

 

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<string.h>
 4 #include<ctype.h>
 5 #include<stdlib.h>
 6 #include <iostream>
 7 #include<algorithm>
 8 #include<queue>
 9 
10 using namespace std;
11 
12 #define N 13000
13 ///12880和3420你选哪个?
14 ///就不告诉你我之前写的是小的,不然也不会把二维的写出来啊,唉
15 int w[N],d[N],dp[N];
16 
17 int main()
18 {
19     int n,k,i,j;
20 
21     while(scanf("%d%d", &n,&k) != EOF)
22     {
23         memset(dp,0,sizeof(dp));///清零清零
24         for(i=0;i<n;i++)
25             scanf("%d %d", &w[i], &d[i]);
26 
27         for(i=0;i<n;i++)
28             for(j=k;j>=w[i];j--)
29             dp[j]=max(dp[j], dp[j-w[i]]+d[i]);
30 
31         printf("%d\n", dp[k]);
32     }
33     return 0;
34 }

 

posted on 2016-08-04 10:26  惟愿。。。  阅读(148)  评论(0编辑  收藏  举报