题意:
有一个存钱罐,不砸碎它,称重得到里面硬币的重量,
硬币分为面值和重量,给定重量和面值,求达到该重量的最小面值
解法:
注意几个问题:1.完全背包的循环方向
2.注意要满足恰好等于给定的重量,不能比它轻或者重,所以对于初始化有要求
3.注意是求最小值,不是常见的最大值
初始化:f数组,0设置为0,其余设置为正无穷
循环方向从0-V闭区间
如果迭代更新了f[v]那么就找到了,否则没找到
#include <iostream>
#include <vector>
#include <map>
#include <list>
#include <set>
#include <deque>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <cstdio>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <cstring>
#include <queue>
using namespace std;
///宏定义
const int INF = 990000000;
const int maxn = 15000 ;
const int MAXN = maxn;
///全局变量 和 函数
int max(int a, int b)
{
return a > b ? a : b;
}
int T;
int E, F;
int N;
int P[maxn];
int W[maxn];
int ffmax[maxn];
int ffmin[maxn];
int main()
{
///变量定义
int i, j, m;
scanf("%d", &T);
int cases = 1;
while(T--)
{
scanf("%d %d", &E, &F);
scanf("%d", &N);
for (i = 0; i < N; i++)
{
scanf("%d %d", &P[i], &W[i]);
}
int V = F - E;
for (i = 0; i <= V; i++)//初始化很关键!
{
ffmax[i] = INF;
}
ffmax[0] = 0;
//0-1背包经典求解
for (i = 0; i < N; i++)
{
for (j = 0; j <= V; j++)
{
if (j >= W[i])
{
if (ffmax[j] > ffmax[j - W[i]] + P[i]) //更改大于小于号!
{
ffmax[j] = ffmax[j - W[i]] + P[i];
}
}
}
}
int ans = ffmax[V];
if (ans != INF)
{
printf("The minimum amount of money in the piggy-bank is %d.\n", ans);
}
else
{
printf("This is impossible.\n");
}
}
///结束
return 0;
}