http://acm.hust.edu.cn/thx/problem.php?id=1254
给定一个价格和一些给定面值的纸币(or硬币),要求能支付这个价格的最少钱数(木有找零),若有多个最少钱数,则要最少张纸币数。
一看,dp,背包问题,然后就果断跳过了。。。没办法,我对dp就是有莫名的距离感。。。。
等到比赛完后再重新看这道题,也是纠结了挺久的说。。。
转移方程:f[j] = min(f[j], f[j - cent[i]] + 1),f[j]表示 j 元最少要f[j]张钱组成。
代码如下:
#include <cstdio>
#include <cstring>
using namespace std;
const int M = 10010;
const int N = 110;
int cent[N], f[M];
void update_min(int& a, int b)
{
if (a > b) a = b;
}
int main()
{
int t, n, m;
for (scanf("%d", &t); t; t--)
{
memset(cent, 0, sizeof(cent));
memset(f, 30, sizeof(f));
int sum = 0;
scanf("%d%d", &m, &n);
for (int i = 0; i < n; i++)
{
scanf("%d", ¢[i]);
sum += cent[i];
}
update_min(sum, 10000);
f[0] = 0;
for (int i = 0; i < n; i++)
for (int j = sum; j >= cent[i]; j--)
update_min(f[j], f[j-cent[i]] + 1);
int money = m;
while (f[money] > n)
money++;
printf("%d %d/n", money, f[money]);
}
}