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;

}

你可能感兴趣的:(uva)