UVA 10306 - e-Coins

这道题考察的是这样的一个问题,在m行的第一列中找一些数,计算它们之和的平方,然后再计算对应的第二列中的那些数的和的平方,这两个数之和为s2就可以了。

这里我借鉴了二维费用的背包问题,易于理解,速度还可以。

代码如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXN 45

int n, m, s;
int a[MAXN][2], f[310][310], x[310], y[310];
void solve()
{
    int p = 0;
    int min = 0x7fffffff;
    for(int i = 0; i <= s; i ++)
        for(int j = 0; j <= s; j ++)
            if(i*i + j*j == s*s)
            {
                x[p] = i;
                y[p] = j;
                p ++;
            }
    if(p == 0) 
        printf("not possible\n");
    else 
    {
        for(int i = 0; i < p; i ++)
        {
            memset(f,1,sizeof(f));
            f[0][0] = 0;
            for(int j = 1; j <= m; j ++)
                for(int k = a[j][0]; k <= x[i]; k ++)
                    for(int g = a[j][1]; g <= y[i]; g ++)
                    {
                        int t = f[k-a[j][0]][g-a[j][1]] + 1;
                        if(t < f[k][g])
                        f[k][g] = t;
                    }
            if(f[x[i]][y[i]] <= 300 && f[x[i]][y[i]] < min)
            min = f[x[i]][y[i]];
        }
        if(min == 0x7fffffff) printf("not possible\n");
        else printf("%d\n",min);
    }
}

void input()
{
    while(scanf("%d",&n) == 1)
        while(n --)
        {
            scanf("%d%d",&m, &s);
            for(int i = 1; i <= m; i ++)
                scanf("%d%d",&a[i][0],&a[i][1]);
            solve();
        }
}
int main()
{
    input();
    return 0;
}
posted on 2012-04-18 15:48  BFP  阅读(317)  评论(0编辑  收藏  举报