UVA10306 - e-Coins(二维完全背包)

来源:互联网 发布:windows 域用户 编辑:程序博客网 时间:2024/06/04 09:34

题意:有n个物品,每个物品有两种价值x, y,每个物品的个数不限,求出(x1 + x2 + ...)^2 + (y1 + y2 + ...) ^2 == S ^ 2


思路:二维完全背包,因为物品个数不限。d[i][j]表示的是能选到的x的和为i,y的和为j时,选择的物品个数最少。 总的价值S为背包的容量,物品的个数为价值。


状态转移方程:d[v1][v2] = min(d[v1][v2], d[v1 - w1[i]][v2 - w2[i]] + 1);


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int INF = 0x3f3f3f3f;const int MAXN = 1005;int d[MAXN][MAXN], w1[MAXN], w2[MAXN];int n, S;int dp() {    for (int i = 0; i < n; i++)        for (int v1 = w1[i]; v1 <= S; v1++)             for (int v2 = w2[i]; v2 <= S; v2++)                 if (d[v1 - w1[i]][v2 - w2[i]] != INF)                     d[v1][v2] = min(d[v1][v2], d[v1 - w1[i]][v2 - w2[i]] + 1);     int ans = INF;     int temp = S * S;    for (int i = 0; i <= S; i++)        for (int j = 0; j <= S; j++)             if (i * i + j * j == temp && d[i][j] != INF)                 if (ans > d[i][j])                    ans = d[i][j];            return ans;}int main() {    int cas;    scanf("%d", &cas);    while (cas--) {        scanf("%d %d", &n, &S);            for (int i = 0; i < n; i++)            scanf("%d %d", &w1[i], &w2[i]);        for (int i = 0; i <= S; i++)            for (int j = 0; j <= S; j++)                d[i][j] = INF;        d[0][0] = 0;        int num = dp();        if (num != INF)            printf("%d\n", num);        else            printf("not possible\n");    }    return 0;}


0 0
原创粉丝点击