uva 10306 - e-Coins

来源:互联网 发布:mac查看php安装目录 编辑:程序博客网 时间:2024/05/24 00:52

题目链接

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

题解:很简单,就是dp【i】【j】就好,每次都有可能达到s*s,都要更新下ans

重点:二维完全背包

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <ctype.h>#include <limits.h>#include <cstdlib>#include <algorithm>#include <vector>#include <queue>#include <map>#include <stack>#include <set>#include <bitset>#define CLR(a) memset(a, 0, sizeof(a))#define REP(i, a, b) for(int i = a;i < b;i++)#define REP_D(i, a, b) for(int i = a;i <= b;i++)typedef long long ll;using namespace std;const int maxn = 300 + 10;const int INF = INT_MAX/2 - 1;int dp[maxn][maxn], s, n;int ans;struct info{    int x, y;};info ren[maxn];void getDp(){    ans = INF;    memset(dp, -1, sizeof(dp));//不能达到    dp[0][0] = 0;//初始化    for(int i = 1;i <= n;i++)    {        for(int a = ren[i].x;a <= s;a++)//二维背包从小到大        {            for(int b = ren[i].y;b <= s;b++)//也是从小到大            {                if(dp[a-ren[i].x][b-ren[i].y]!=-1&&( dp[a][b]==-1|| (dp[a-ren[i].x][b-ren[i].y]+1<dp[a][b]) ) )//可以更新dp【a】【b】                {                    dp[a][b] = dp[a-ren[i].x][b-ren[i].y]+1;                    if(a*a + b*b == s*s)//直接统计就好                    {                        ans = min(ans, dp[a][b]);                    }                }            }        }    }}void solve(){    getDp();    if(ans != INF)        printf("%d", ans);    else    {        printf("not possible");    }    printf("\n");}int main(){  //  freopen("3Cin.txt", "r", stdin);    //freopen("3Cout.txt", "w", stdout);    int ncase;    scanf("%d", &ncase);    while(ncase--)    {        scanf("%d%d", &n, &s);        REP_D(i, 1, n)        {            scanf("%d%d", &ren[i].x, &ren[i].y);        }        solve();    }    return 0;}


0 0