您的位置:首页 > 其它

POJ - 1384 Piggy-Bank(完全背包)

2018-03-02 20:18 453 查看
题意:
       有n种硬币,每种硬币有各自的重量w[i] 克和它对应的价值v[i]. 每种硬币可以无限使用.(完全背包问题)
      已知一个储蓄罐中所有硬币的总重量正好为m克, 问你这个储蓄罐中最少有多少价值的硬币? 
      如果m克的情况不存在, 输出“This is impossible.”.

解题思路:
      动态规划问题,主要就是找到子问题,并且子问题有后效性.(即知道i的状态就可以推出i+1的状态).

      本题的子问题就是用dp[i][j]表示只用前i种货币,剩余质量达j克时所能达到的最小价值.

      dp[i][j] = min(dp[i-1][j] , dp[i][ j - w[i] ] + v[i])

小细节:
       因为是取小,所以初始化为无穷大.

       如果dp[total]是无穷大的话,则输出impossible.

       采取滚动数组.

下面是代码.#include <cstdio>
#include <algorithm>

using namespace std;
#define INF 1e9

int v[600],w[600],dp[11000];

int main()
{
int t,e,f,n,total;
int i,j;
scanf("%d",&t);

while(t--)
{
scanf("%d%d",&e,&f);
total = f-e;
scanf("%d",&n);
for(i = 0;i < n;i++)
{
scanf("%d%d",&v[i],&w[i]);
}
dp[0] = 0;
for(i = 1;i <= total;i++)
{
dp[i] = INF;
}
for(i = 0;i < n;i++)
{
if(i == 0)
{
for(j = 1;j*w[i] <= total;j++)
{
dp[j*w[i]] = v[i]*j;
}
}
else
{
for(j = w[i];j <= total;j++)
{
dp[j] = min(dp[j],dp[j-w[i]]+v[i]);
}
}
}
if(dp[total] != INF)
{
printf("The minimum amount of money in the piggy-bank is %d.\n",dp[total]);
}
else
printf("This is impossible.\n");
}

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