题目大意:给出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;
}