题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1114
题意:我们知道存钱罐存放的coins的重量为C,有N种coin,每种coin有两种属性:p(价值),w(重量),该重量下让我们求最少的coins的价值。
题解:
我们用dp[ i ]来表示重量为i的时候最少的金币价值。
我们对dp进行初始化,因为price的范围在[1,5e4],然后dp是price叠加的所以保险起见还是用INF进行初始化。再者的话,对dp进行初始化的时候应该是按照重量的范围,而不是金币的种类数。(卡了三天就卡在了这两点QAQ,这个事情还告诉我,当局者迷,旁观者清QAQ,这句话当真没错,我干嘛不重新敲一遍,一直看看看,还看不出来什么QAQ)
然后的话就是很常规的完全背包了,取最小值即可。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <list>
#include <map>
#define P(x) x>0?x:0
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef vector<int>:: iterator VITer;
const int maxc=1e4+5;
const int maxN=505;
int dp[maxc];//maxc重的货币的最小价值
int N,E,F,C;
struct node
{
int p,w;
node(int a=0,int b=0):p(a),w(b){}
friend bool operator < (node n1,node n2)
{
return n1.w>n2.w;
}
}coin[maxN];
void init()
{
for(int i=0;i<maxc;i++)
{
dp[i]=INF;//price的范围在[1,5e4],更何况dp是price叠加的所以保险起见还是用INF
}
dp[0]=0;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d%d",&E,&F);
C=F-E;//货币的重量,有可能为0
scanf("%d",&N);
for(int i=1;i<=N;i++)
{
scanf("%d%d",&coin[i].p,&coin[i].w);//有N种货币
}
for(int i=1;i<=N;i++)//N种货币
{
for(int j=coin[i].w;j<=C;j++)//重量一定
{
dp[j]=min(dp[j],dp[j-coin[i].w]+coin[i].p);
}
}
if(dp[C]==INF)
printf("This is impossible.\n");
else
printf("The minimum amount of money in the piggy-bank is %d.\n",dp[C]);
}
return 0;
}