洛谷P1411 砝码称重
传送门啦
这个题总体思路就是先搜索在 $ dp $
void dfs(int keep,int now){
//使用 放弃
if(now > m) return;
//已经放弃超过m个了,就退出
if(keep == n){
if(now == m) dp();
return ;
}
///如果搜索完后正好符合条件,执行一次dp过程
dfs(keep + 1 , now);
//这个砝码选
vis[keep] = true;//打标记
dfs(keep + 1 , now + 1);
//这个砝码放弃
vis[keep] = false;//取消标记
}
观察题目可得,这个过程可以通过01背包实现。
定义 $ f[i][j] $ 为当前选取到了第j个砝码,如果通过之前的砝码可以称量出重量 $ i $ 那么 $ f[i][j] $ 的值为 $ true $ 。
状态转移方程为: $ f[i][j]=f[i-a[i]][j-1] $
初始状态为 $ f[0][j]=true $
最后 $ f[i][n] $ 中 $ true $ 的个数就是通过这些砝码可以计算出的重量值。通过一维数组,我们可以只定义一个 $ f[i] $ 数组,降低了时间复杂度,注意此时内层循环倒序。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
inline int read(){
char ch = getchar();
int f = 1 , x = 0;
while(ch > '9' || ch < '0'){if(ch == '-')f = -1;ch = getchar();}
while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + ch - '0';ch = getchar();}
return x * f;
}
int n,m,a[300];
bool vis[300];
int ans,f[3000],tot,res;
void dp(){
memset(f , 0 , sizeof(f));
f[0] = true; ans = tot = 0;
for(int i=0;i<n;i++){
if(vis[i]) continue;
for(int j=tot;j>=0;j--)
if(f[j] && !f[j+a[i]]){
f[j+a[i]] = true;
ans++;
}
tot += a[i];
}
res = max(ans , res);
}
void dfs(int keep,int now){
//使用 放弃
if(now > m) return;
if(keep == n){
if(now == m) dp();
return ;
}
dfs(keep + 1 , now);
vis[keep] = true;
dfs(keep + 1 , now + 1);
vis[keep] = false;
}
int main(){
n = read(); m = read();
for(int i=0;i<n;i++) {
a[i] = read();
}
dfs(0 , 0);
printf("%d\n",res);
return 0;
}
洛谷P1411 砝码称重的更多相关文章
- 洛谷P1441 砝码称重(搜索,dfs+bitset优化)
洛谷P1441 砝码称重 \(n\) 的范围为 \(n \le 20\) ,\(m\) 的范围为 \(m \le 4\) . 暴力遍历每一种砝码去除情况,共有 \(n^m\) 种情况. 对于剩余砝码求 ...
- 洛谷P1441 砝码称重(搜索,dfs+dp)
洛谷P1441 砝码称重 \(n\) 的范围为 \(n \le 20\) ,\(m\) 的范围为 \(m \le 4\) . 暴力遍历每一种砝码去除情况,共有 \(n^m\) 种情况. 对于剩余砝码求 ...
- 洛谷P1441 砝码称重
P1441 砝码称重 题目描述 现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0). 输入输出格式 输入格式: 输入文件weight.in ...
- 洛谷 P2347 砝码称重
P2347 砝码称重 题目描述 设有1g.2g.3g.5g.10g.20g的砝码各若干枚(其总重<=1000), 输入输出格式 输入格式: 输入方式:a1 a2 a3 a4 a5 a6 (表示1 ...
- 洛谷P2347 砝码称重 [2017年4月计划 动态规划01]
P2347 砝码称重 题目描述 设有1g.2g.3g.5g.10g.20g的砝码各若干枚(其总重<=1000), 输入输出格式 输入格式: 输入方式:a1 a2 a3 a4 a5 a6 (表示1 ...
- 洛谷P2347 砝码称重 【多重背包】(方案数)(经典)
题目链接:https://www.luogu.org/problemnew/show/P2347 题目描述 设有1g.2g.3g.5g.10g.20g的砝码各若干枚(其总重<=1000), 输入 ...
- 洛谷 P2347 砝码称重 != codevs 2144
题目描述 设有1g.2g.3g.5g.10g.20g的砝码各若干枚(其总重<=1000), 输入输出格式 输入格式: 输入方式:a1 a2 a3 a4 a5 a6 (表示1g砝码有a1个,2g砝 ...
- 洛谷——P2347 砝码称重
https://www.luogu.org/problem/show?pid=2347#sub 题目描述 设有1g.2g.3g.5g.10g.20g的砝码各若干枚(其总重<=1000), 输入输 ...
- 洛谷 P1441 砝码称重
题目描述 现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0). 输入输出格式 输入格式: 输入文件weight.in的第1行为有两个整数n ...
随机推荐
- 「CodePlus 2017 12 月赛」火锅盛宴(模拟+树状数组)
1A,拿来练手的好题 用一个优先队列按煮熟时间从小到大排序,被煮熟了就弹出来. 用n个vector维护每种食物的煮熟时间,显然是有序的. 用树状数组维护每种煮熟食物的数量. 每次操作前把优先队列里煮熟 ...
- Dockerfile编写注意事项
转载自:https://blog.fundebug.com/2017/05/15/write-excellent-dockerfile/ 一.目标 更快的构建速度 更小的Docker镜像大小 更少的D ...
- Linux运维五:定时任务crond服务
一.crond简介 crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动cro ...
- 最短路径算法的实现(dijskstra):Python
dijskstra最短路径算法步骤: 输入:图G=(V(G),E(G))有一个源顶点S和一个汇顶点t,以及对所有的边ij属于E(G)的非负边长出cij. 输出:G从s到t的最短路径的长度. 第0步:从 ...
- Redis总体 概述,安装,方法调用
1 什么是redis redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合)和zset( ...
- bzoj千题计划133:bzoj3130: [Sdoi2013]费用流
http://www.lydsy.com/JudgeOnline/problem.php?id=3130 第一问就是个最大流 第二问: Bob希望总费用尽量大,那肯定是把所有的花费加到流量最大的那一条 ...
- [NOI1997] 积木游戏
COGS 261. [NOI1997] 积木游戏 http://www.cogs.pro/cogs/problem/problem.php?pid=261 ★★ 输入文件:buildinggame ...
- Java并发编程原理与实战二十七:循环栅栏:CyclicBarrier
昨天我们学习了倒计数功能的等待,今天我们学习的是循环栅栏:CyclicBarrier.下面我们就开始吧: 1.CyclicBarrier简介CyclicBarrier,是JDK1.5的java.uti ...
- JS替换地址栏参数值
首先,页面引入JS代码片段(整体复制粘贴即可): var Query=function(a){"use strict";var b=function(a){var b=[],c,d ...
- XML学习(1)
什么是XML? XML是可拓展标记语言,类似HTML,它的设计宗旨是为了传输数据,而不是像HTML那样显示数据.XML标签没有被预定义,需要用户自定义标签. xml文档必须包含根元素,它是其他所有元素 ...