UVA 10306 - e-Coins
这道题考察的是这样的一个问题,在m行的第一列中找一些数,计算它们之和的平方,然后再计算对应的第二列中的那些数的和的平方,这两个数之和为s2就可以了。
这里我借鉴了二维费用的背包问题,易于理解,速度还可以。
代码如下:
#include<stdio.h> #include<string.h> #include<stdlib.h> #define MAXN 45 int n, m, s; int a[MAXN][2], f[310][310], x[310], y[310]; void solve() { int p = 0; int min = 0x7fffffff; for(int i = 0; i <= s; i ++) for(int j = 0; j <= s; j ++) if(i*i + j*j == s*s) { x[p] = i; y[p] = j; p ++; } if(p == 0) printf("not possible\n"); else { for(int i = 0; i < p; i ++) { memset(f,1,sizeof(f)); f[0][0] = 0; for(int j = 1; j <= m; j ++) for(int k = a[j][0]; k <= x[i]; k ++) for(int g = a[j][1]; g <= y[i]; g ++) { int t = f[k-a[j][0]][g-a[j][1]] + 1; if(t < f[k][g]) f[k][g] = t; } if(f[x[i]][y[i]] <= 300 && f[x[i]][y[i]] < min) min = f[x[i]][y[i]]; } if(min == 0x7fffffff) printf("not possible\n"); else printf("%d\n",min); } } void input() { while(scanf("%d",&n) == 1) while(n --) { scanf("%d%d",&m, &s); for(int i = 1; i <= m; i ++) scanf("%d%d",&a[i][0],&a[i][1]); solve(); } } int main() { input(); return 0; }