UVA 10306 (二维完全背包)
UVA 10306
题意:
有种新货币,它的价值有两个值 x 和 y,
有一种 e-modulus 值, 计算方式为 sqrt(X*X + Y*Y);
其中 X 和 Y 分别是所有货币 x 值的总和 和 y 值的总和,
即 (x1 + x2 +... +xm)^2 + (y1 + y2 +...+ym)^2 = s^2;
给出 e-modulus 的值 s , 每种货币的数量无限, 求满足 S 值的货币的最小数量。
输入:
第一行输入 n , n 组测试;
第二行 m , s ;表示有 m 中货币,e-modulus 的值是 s;
接下来 m 行,每行两个数, 表示货币的 x 值和 y 值。
输出满足 s 值的货币的最小数量, 如果不能则输出 “not possible”。
解题:
由每种无限件可想到完全背包,
d[i][j] 表示 x 值的和为 i ,y值的和为 j 时货币的最小数量,
d[j][k] = min (d[j][k], d[j-x[i]][k-y[i]] + 1 ); 当(i*i)+(j*j) == s*s 时更新答案。
初始化除 d[0][0] = 0, 其余 INF ;
#include <bits/stdc++.h> #define ll long long using namespace std; const int maxn = 1010; const int INF = 0x3f3f3f3f; int x[50], y[50], d[maxn][maxn]; int main() { int t, m, s; scanf ("%d", &t); while (t --) { scanf ("%d%d", &m, &s); for (int i = 0; i < m; i ++) scanf ("%d%d", &x[i], &y[i]); memset (d, INF, sizeof (d)); d[0][0] = 0; int ans = INF; for (int i = 0; i < m; i ++) { for (int j = x[i]; j <= s; j ++) { for (int k = y[i]; k <= s; k ++) { d[j][k] = min (d[j][k], d[j-x[i]][k-y[i]] + 1 ); if(j*j + k*k == s*s) ans = min (ans, d[j][k]); } } } printf ((ans == INF) ? "not possible\n" : "%d\n", ans); } return 0; }