UVA - 10306 e-Coins

题目大意:给出m和s, 再给出m种电子硬币,每种硬币有两种金额xi,yi。现在要在m种硬币种选若干个硬币,可以重复选同一种硬币, 使得(x1 + x2 + .... + xn) ^ 2 + (y1 + y2 + ... + yn) ^ 2 == s * s, 要求n尽量小,(n为选取硬币的个数), 如果不能选出满足条件的硬币,输出-1。


解题思路:二维的完全背包问题,注意要用long long。

#include <iostream>
using namespace std;

int main() {
	int n, m, S, DP[305][305], A[45][45];
	cin >> n;
	while (n--) {
		cin >> m >> S;
		for (int i = 0; i < m; i++)
			cin >> A[i][0] >> A[i][1];

		for (int i = 0; i <= S; i++)
			for (int j = 0; j <= S; j++)
				DP[i][j] = 999999;
		DP[0][0] = 0;

		for (int i = 0; i < m; i++)
			for (int j = A[i][0]; j <= S; j++)
				for (int k = A[i][1]; k <= S; k++)
					if (DP[j-A[i][0]][k-A[i][1]] != 999999)
						DP[j][k] = min(DP[j][k], DP[j-A[i][0]][k-A[i][1]] + 1);
			
		int ans = 999999;
		for (int i = 0; i <= S; i++)
			for (int j = 0; j <= S; j++)
				if (i * i + j * j == S * S)
					ans = min(ans, DP[i][j]);
	
		if (ans == 999999)
			cout << "not possible\n";
		else
			cout << ans << endl;
	}
	return 0;
}


你可能感兴趣的:(UVA - 10306 e-Coins)