您的位置:首页 > 其它

HDU 2602 动态规划01背包

2016-04-16 15:34 274 查看




01背包的状态转换方程 f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ),  f[i-1,j] }

f[i,j]表示在前i件物品中选择若干件放在承重为 j 的背包中,可以取得的最大价值。

Pi表示第i件物品的价值。

决策:为了背包中物品总价值最大化,第 i件物品应该放入背包中吗 ?

【以上文字来源】【http://blog.csdn.net/mu399/article/details/7722810】

【以下题目来源】【http://acm.hdu.edu.cn/showproblem.php?pid=2602】

以下是一道最简单的01背包动态规划,几乎不用修改状态转移方程,然而还是有那么几个坑点。


Bone Collector


Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)


Total Submission(s) : 4   Accepted Submission(s) : 3


Problem Description

Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …

The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the
maximum of the total value the bone collector can get ?



 

Input

The first line contain a integer T , the number of cases. Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain
N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.

 

Output

One integer per line representing the maximum of the total value (this number will be less than 2[sup]31[/sup]).

 

Sample Input

1
5 10
1 2 3 4 5
5 4 3 2 1

 

Sample Output

14

 

<pre name="code" class="cpp">#include<stdio.h>
#include<string.h>

int dp[1010][1010];   //状态储存

struct bone{    //结构体数组,储存骨头的价值和体积
int value;
int volume;
}bon[1010];

int max(int a,int b)   //比较函数
{
if(a>=b)
return a;
return b;
}

int main()
{
int T;

scanf("%d",&T);
while(T--)
{
int n,v;
int i,j;

scanf("%d%d",&n,&v);

for(i=1;i<=n;i++)
scanf("%d",&bon[i].value);
for(i=1;i<=n;i++)
scanf("%d",&bon[i].volume);

memset(dp,0x0, sizeof(dp));     //这边二维数组的赋值也要高亮。

for(i=1;i<=n;i++)                 //这两个循环上面的0和1挺重要的。原因如下①
{
for(j=0;j<=v;j++)
{
if(j-bon[i].volume<0)             //高亮,不太明白为什么有些旁友们不加这句话怎么会对QAQ
dp[i][j]=dp[i-1][j];
else
dp[i][j]=max(dp[i-1][j-bon[i].volume]+bon[i].value,dp[i-1][j]);
}
}
/*	for(i=0;i<=n;i++)              //打表
{
for(j=0;j<=v;j++)
printf("%d ",dp[i][j]);
printf("\n");
}*/
printf("%d\n",dp
[v]);
}
return 0;
}




①一开始我为了方便所以就两层都从1开始,导致了坑点1、测试组里面居然存在没有体积但是有价值的骨头????excuse me??

测试组1的打表


输入

1

5 10

1 2 3 4 5

5 4 3 2 1


DP[][]

骨头\体积012345678910
000000000000
100000111111
200002222233
300033335555
400447777799
50559991212121214


输出

14

测试组2的打表(存在骨头体积为0但有价值)


输入

1
5 0
2 4 1 5 1
0 0 1 0 0

DP[][]

骨头\体积0 
00 
12 
26 
36 
411 
512 


输出

12
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息