http://acm.hdu.edu.cn/showproblem.php?pid=1114
完全背包求最小值
这题貌似正着求一次 用个二维就行了
我的方法有点2B 反着求 用了二进制优化
二维的懒的写了
代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
using namespace std;
int f[10005];
struct node
{
int value;
int weight;
}num[505],d[505];
const int inf=200000000;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int empty;
int full;
scanf("%d%d",&empty,&full);
int m=full-empty;
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&num[i].value,&num[i].weight);
for(int i=0;i<=m;i++)
if(i==0)
f[i]=0;
else
f[i]=inf;
for(int i=1;i<=n;i++)
{
int knum=m/num[i].weight;
if(knum<=0)
continue;
int len=0;
int sign=1;
while(knum-sign*2+1>0)
{
d[len].value=num[i].value*sign;
d[len].weight=num[i].weight*sign;
len++;
sign*=2;
}
d[len].value=(knum-sign+1)*num[i].value;
d[len].weight=(knum-sign+1)*num[i].weight;
len++;
for(int j=0;j<len;j++)
for(int k=m;k>=d[j].weight;k--)
{
f[k]=min(f[k],f[k-d[j].weight]+d[j].value);
}
}
if(f[m]!=inf)
printf("The minimum amount of money in the piggy-bank is %d.\n",f[m]);
else
printf("This is impossible.\n");
}
}