题解 SP39 【PIGBANK - Piggy-Bank】
关于这道题。。。。其实就是个完全背包,这道题要求的是装满之后的最小值而不是最大值,就把max改成min,然后数组初始化的时候初始化成一个比较大的数就可以(之前初始化成二十万,结果WA到怀疑人生,在后面加个0成了二百万就AC了。。。)。 先放一下AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#define INF 2000000
using namespace std;
int T,E,F,N,P,W;
int weight[505],value[505];
int qwq[10005];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&E,&F);
int w=F-E;
// initialize the array
qwq[0]=0;
for(int i=1;i<=w;i++) qwq[i]=INF;
scanf("%d",&N);
// intput the weight and value of each coin
for(int i=0;i<N;i++) scanf("%d%d",&value[i],&weight[i]);
for(int i=0;i<N;i++)
{
for(int k=weight[i];k<=w;k++)
{
qwq[k]=min(qwq[k],qwq[k-weight[i]]+value[i]);
}
}
if(qwq[w]>=INF) printf("This is impossible.\n");
else printf("The minimum amount of money in the piggy-bank is %d.\n",qwq[w]);
}
return 0;
}
做这道题的时候,有个比较难想的地方好弱啊,就是怎么保证这个是存满的。
如果是写个循环然后+1,貌似看起来肯定能遍历到qwq[w]这个位置从而对这个值进行min操作,看起来貌似总是能找到最小值。然后当时我就懵了不知道怎么保证找到impossible的情况。。
我们可以看一下我们的转移方程:qwq[k]=min(qwq[k],qwq[k-weight[i]]+value[i]);
由于在这个操作之前,我们把qwq数组的每一个位置都初始化成了2000000,那么,如果是impossible,那么qwq[k]和qwq[k-weight[i]]这两个位置的值都是2000000,那么对qwq[k]和qwq[k-weight[i]]+value取最小值,那肯定还是2000000。所以说qwq[w]这个位置肯定是被取过最小值,只是取了最小值之后他本身的值没变。