【2015の复活】砝码称重v2
2015-10-18 21:10
225 查看
Problem
Background
设有 1g, 2g, 3g, 5g, 10g, 20g 的砝码各若干枚(其总重 ≤ 100, 000),要求:计算用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况。
Input
一行,包括六个正整数 a 1 , a 2 , a 3 , a 4 , a 5 , a 6 ,表示 1g 砝码有 a 1 个,2g 砝码有 a 2 个,……,20g 砝码有 a 6 个。相邻两个整数之间用单个空格隔开。
Output
以“Total=N”的形式输出,其中 N 为可以称出的不同重量的个数。Example
weight.in1 1 0 0 0 0
weight.out
Total=3
Explanation
样例给出的砝码可以称出 1g, 2g, 3g 三种不同的重量。Scoring
• 对于 20% 的数据,砝码总个数不超过 20。• 对于 40% 的数据,砝码总个数不超过 800。
Solution
也是一道NOI OpenJudge上的一道题这题首先是一个背包问题,转移状态可行性。
dp[i][j]表示第i个包,总重为j的可行性
dp[i][j] |= dp[i - 1][j - k * c[i]]
然后采用二进制优化
用一个bitset,第i为表示重量为i的可行性
将每个ai拆分20,21,22…2ki,pi
每次更新bitset即为A|=A<<ci∗a′i
统计A中1的个数
Code
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i = (a); i <= (b); i++) #define red(i, a, b) for (int i = (a); i <= (b); i--) #define ll long long const int N = 110000; int v[6] = {1, 2, 3, 5, 10, 20}; int sum, ans, m; int k[10], f[150000], num[150000]; bitset <N> A; int main() { rep(i, 0, 5) scanf("%d", &k[i]); m = 0; rep(i, 0, 5) { int base = 1; while(k[i] >= base) { num[++m] = base * v[i]; k[i] -= base; base *= 2; } if (k[i] > 0) num[++m] = k[i] * v[i]; } A[0] = 1; rep(i, 1, m) A |= (A << num[i]); printf("Total=%d\n", A.count() - 1); return 0; }
这几天的吐槽会专门开一篇的
End.
相关文章推荐
- 【自考】——考后总结
- 腐蚀与膨胀
- Linux流量监控工具
- 智能手环: 调研报告
- IOS沙盒中的Documents、Library、tmp区别
- 用Eclipse构建Maven项目
- AMD 和 CMD as lazy as possible
- android animation
- 模板类中重载<<和>>操作符
- 基于Annotation的SpringMVC4整合Hibernate4 + freemarker
- mac已安装xctool而简单的执行xctool打包
- MvvmLight框架使用入门(一)
- 软件缺陷的严重性和优先级
- 二十三种设计模式之行为型模式之解释器模式
- 《信息系统开发与管理之DFD》
- 实验三 敏捷开发与Xp实践
- How to install php evn on ubuntu
- 敏捷开发与敏捷测试
- 2.9 初始化进程0
- android clipPath切割画布