UVa 10306 - e-Coins

传送门

UVa 10306 - e-Coins

题意

给出数据组数和s,求能不能凑硬币,使得$x^2 + y^2 = s^2$,求出最小硬币个数。

思路

一开始只想着用dp[i]表示凑成i所需的最少硬币,想了很久没想出来。
还是参考了一帆的解题报告
用dp[i][j]表示凑成$x = i, y = j$所需的最少数量。

状态转移方程$dp[i][j] = min(dp[i - coin[k].td][j - coin[k].it] + 1, dp[i][j])$

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 300 + 10;
const int INF = 0x3f3f3f3f;
 
struct COIN
{
    int td, it;
}coin[50];
 
int dp[MAXN][MAXN];
 
int GetValue(int i, int j)
{
    return i * i + j * j;
}
 
int main()
{
    //freopen("in.txt", "r", stdin);
    int T, i, j, n, s, money, k, ans;
    scanf("%d", &T);
    while (T--)
    {
        scanf("%d%d", &n, &s);
        for (i = 0; i < n; i++)
            scanf("%d%d", &coin[i].td, &coin[i].it);
        for (i = 0; i <= s; i++)
            for (j = 0; j <= s; j++)
                dp[i][j] = INF;
        dp[0][0] = 0;
        ans = INF;
        for (i = 0; i < n; i++)
            for (j = 0; j <= s; j++)
                for (k = 0; k <= s; k++)
                {
                    if (j - coin[i].td >= 0 && k - coin[i].it >= 0 && GetValue(j, k) <= s * s && dp[j - coin[i].td][k - coin[i].it] != INF)
                    {
                        dp[j][k] = min(dp[j][k], dp[j - coin[i].td][k - coin[i].it] + 1);
                        if (GetValue(j, k) == s * s)
                            ans = min(ans, dp[j][k]);
                    }
                }
        if (ans != INF)
            printf("%d\n", ans);
        else
            printf("not possible\n");
    }
    return 0;
}

Powered by Jekyll and Theme by solid