题目大意:给出n种硬币,每一个硬币有两种价值x和y,要求求出满足m = (x^2+y^2)的最少的硬币数量,其中x是选出的硬币的所有x的值的和,y是所有选出的硬币的y的值的和
解题思路:和01背包的无限物品的相似,只不过这次是二维的,权值是1,容量是m
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 305
#define INF 0x3f3f3f3f
int dp[maxn][maxn],c[45][2];
int m,S;
int main() {
int test;
scanf("%d", &test);
while(test--) {
scanf("%d%d", &m, &S);
for(int i = 0; i < m; i++)
scanf("%d%d",&c[i][0],&c[i][1]);
for(int i = 0; i <= S; i++)
for(int j = 0; j <= S; j++)
dp[i][j] = INF;
dp[0][0] = 0;
for(int i = 0; i < m; i++)
for(int j = c[i][0]; j <= S ;j++)
for(int k = c[i][1]; k <= S; k++)
if(dp[j-c[i][0]][k-c[i][1]] != INF) {
dp[j][k] = min(dp[j-c[i][0]][k-c[i][1]]+1,dp[j][k]);
}
int ans = INF;
for(int i = 0; i <= S; i++)
for(int j = 0; j <= S; j++)
if(i*i+j*j == S*S && dp[i][j] !=INF)
ans = min(ans,dp[i][j]);
if(ans != INF)
printf("%d\n",ans);
else
printf("not possible\n");
}
return 0;
}