Piggy-Bank HDU - 1114
题意:
在可以开展ACM之前,必须提前做好预算并获得经济上的支持。其中主要的利润来自IBM。背后的想法很简单。无论什么时候ACM有钱了,他就把所有的硬币存进一个存储罐里面。你也指导这个行为事不可逆转的,你只有打破存储罐才能拿到钱。一段时间过去,钱罐里面就会存满。但是问题是,不能知道存钱罐里面的钱数。所以唯一一个办法就是称重。然后猜大概有多少钱在里面。我们可以准确的称出重量,并且知道所有给定货币的所有的硬币重里。我i们可以保证最少的钱在猪里面。
输入:T,E(空猪)F(满猪)然后给出N代表n种货币P(value)和W(重量)
输出:从E到F,最小钱数。不能到达就输出This is impossible.
思路:惊讶秒A了。开心一下虽然感觉也不是很难,毕竟像我这样的菜鸟都有一点的思路,本来是想按照另一个思路写的,但是卡住了。然后还是动规的考虑,求dp[i]表示当前i重量下最小的钱数。所以可以得到这样的dp[i]=min(dp[i-w[j]],dp[i])。然后尝试这样写出来然后就过了,也不需要排序,其实排序的思想是之前学的贪心然后觉得差不多可以试试,但是好像不太行,想出转移方程,然后就过啦>_<。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int inf=0x7f7f7f;
int n,m;
int dp[10000+10];
struct node{
int p,w;
double pw;
bool operator <(const node &u)const{
return pw<u.pw;
}
}coin[500+10];
int main()
{
int T;
int E,F;
int n,p,w;//n<=500
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&E,&F,&n);
for(int i=0;i<n;i++)
{
scanf("%d%d",&coin[i].p,&coin[i].w);
coin[i].pw=(double)coin[i].p/(double)coin[i].w;
}
// sort(coin,coin+n);
memset(dp,inf,sizeof(dp));
dp[E]=0;
for(int i=E;i<=F;i++)
{
for(int j=0;j<n;j++)
{
if(i-coin[j].w<E) continue;
dp[i]=min(dp[i-coin[j].w]+coin[j].p,dp[i]);
}
}
if(dp[F]<inf)
printf("The minimum amount of money in the piggy-bank is %d.\n",dp[F]);
else
printf("This is impossible.\n");
}
return 0;
}