• uva 10306


    题目链接: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
    ", ans - 1);
    	else
    	    printf("not possible
    ");
        }
        return 0;
    }
    


  • 相关阅读:
    FTP服务总结
    编译安装hpptd2.4
    搭建DNS服务
    定制简单的Linux系统
    建立私有CA
    关于/boot文件的修复实验
    shell脚本进阶(二)
    datetime模块日期转换和列表sorted排序
    linux操作命令
    Python 中的特殊双下划线方法
  • 原文地址:https://www.cnblogs.com/pangblog/p/3328921.html
Copyright © 2020-2023  润新知