首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

uva 10306 - e-Coins(完全双肩包)

2013-09-18 
uva 10306 - e-Coins(完全背包)题目链接:10306 - e-Coins题目大意:给出m和s, 再给出m种电子硬币,每种硬币

uva 10306 - e-Coins(完全背包)

题目链接:10306 - e-Coins


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


解题思路:二维的完全背包问题,注意要用long long。


#include <stdio.h>#include <string.h>const int N = 305;struct coin{    int x;    int y;}val[50];int n, s, S, dp[N][N];void read() {   memset(val, 0, sizeof(val));   scanf("%d%d", &n, &s);   S = s * s;   for (int i = 0; i < n; i++)       scanf("%d%d", &val[i].x, &val[i].y);}int solve() {    int cnt = 1 << 30;    memset(dp, 0, sizeof(dp));    dp[0][0] = 1;    for (int k = 0; k < n; k++) {for (int i = 0; i <= s; i++) {    for (int j = 0; j <= s; j++) {if (dp[i][j]) {    int p = i + val[k].x, q = j + val[k].y;    if (p > s || q > s) break;    if (dp[p][q] == 0 || dp[i][j] + 1 < dp[p][q])dp[p][q] = dp[i][j] + 1;    if (p * p + q * q == S && dp[p][q] < cnt)cnt = dp[p][q];}    }}    }    if (cnt == 1 << 30) return 0;    else return cnt;}int main() {    int cas;    scanf("%d", &cas);    while (cas--) {read();int ans = solve();if (ans)    printf("%d\n", ans - 1);else    printf("not possible\n");    }    return 0;}


热点排行