首页 > 代码库 > 洛谷P2347 砝码称重 [2017年4月计划 动态规划01]
洛谷P2347 砝码称重 [2017年4月计划 动态规划01]
P2347 砝码称重
题目描述
设有1g、2g、3g、5g、10g、20g的砝码各若干枚(其总重<=1000),
输入输出格式
输入格式:输入方式:a1 a2 a3 a4 a5 a6
(表示1g砝码有a1个,2g砝码有a2个,…,20g砝码有a6个)
输出格式:输出方式:Total=N
(N表示用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况)
输入输出样例
输入样例#1:
1 1 0 0 0 0
输出样例#1:
Total=3
暴力算法略,这里只讲dp。
背包问题,每个砝码选或不选,显然01背包。
我们把砝码按照从小到大的顺序依次排开
f[i][j]表示前i个砝码能否组成质量j。
转移:f[i][j] = f[i-1][j] || f[i-1][j-w[i]],w[i]表示第i件物品(砝码)的价值(质量),k为第i件物品(砝码)的数量
常规压缩一维:f[j] = f[j] || f[j-k*w[i]]
代码中做了这样的处理:用i和j来共同控制第i件物品。
代码如下:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>inline int read(){ int x = 0;char ch = getchar();char c = ch; while(ch > ‘9‘ || ch < ‘0‘)c = ch,ch = getchar(); while(ch <= ‘9‘ && ch >= ‘0‘)x = x * 10 + ch - ‘0‘,ch = getchar(); if(c == ‘-‘)return -1 * x; return x;}const int INF = 99999999999;int sum;int w[7] = {0,1,2,3,5,10,20};bool f[1010];int num[10];int ans;int main(){ for(int i = 1;i <= 6;i ++) { num[i] = read(); sum += num[i] * w[i]; } f[0] = true; for(int i = 1;i <= 6;i ++) { for(int j = 1;j <= num[i];j ++) { for(int k = sum;k >= w[i];k --) { if(f[k - w[i]])f[k] = true; } } } for(int i = 1;i <= sum;i ++) { if(f[i])ans ++; } printf("Total=%d", ans); return 0;}
洛谷P2347 砝码称重 [2017年4月计划 动态规划01]
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。