您的位置:首页 > 其它

uva 10306 简单DP

2015-04-02 20:56 337 查看
题意:

给n种硬币和一个面值s。

每种硬币有两种价值,并且有无限个,求能满足第一种价值i * i + j * j = s * s的最少硬币数。

解析:

先dp出每种情况下i,j用的最少银币,然后暴力搞一下找出和规则的就好,和给俩棒子找最小差距那题有点像。

详见代码。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>

#define LL long long

using namespace std;
const int maxn = 300 + 10;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const double pi = 4 * atan(1.0);
const double ee = exp(1.0);

int w1[maxn], w2[maxn];
int dp[maxn][maxn];

int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif // LOCAL
int ncase;
scanf("%d", &ncase);
while (ncase--)
{
int n, s;
scanf("%d%d", &n, &s);
for (int i = 0; i <= s; i++)
{
for (int j = 0; j <= s; j++)
{
dp[i][j] = inf;
}
}
for (int i = 0; i < n; i++)
{
scanf("%d%d", &w1[i], &w2[i]);
dp[w1[i]][w2[i]] = 1;
}
for (int i = 0; i < n; i++)
{
for (int j = w1[i]; j <= s; j++)
{
for (int k = w2[i]; k <= s; k++)
{
dp[j][k] = min(dp[j][k], dp[j - w1[i]][k - w2[i]] + 1);
}
}
}
int ans = inf;
for (int i = 0; i <= s; i++)
{
for (int j = 0; j <= s; j++)
{
if (i * i + j * j == s * s)
{
ans = min(dp[i][j], ans);
}
}
}
if (ans == inf)
printf("not possible\n");
else
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: