P1441 砝码称重 DFS回溯+DP
题目描述
现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0)。
请注意,砝码只能放在其中一边。
输入输出格式
输入格式:
输入文件weight.in的第1行为有两个整数n和m,用空格分隔
第2行有n个正整数a1,a2,a3,……,an,表示每个砝码的重量。
输出格式:
输出文件weight.out仅包括1个整数,为最多能称量出的重量数量。
输入输出样例
说明
【样例说明】
在去掉一个重量为2的砝码后,能称量出1,2,3共3种重量。
【数据规模】
对于20%的数据,m=0;
对于50%的数据,m≤1;
对于50%的数据,n≤10;
对于100%的数据,n≤20,m≤4,m<n,ai≤100。
一开始总想着骚操作 但是细节太多处理不了
直接暴力搜索就能过的。。。。
没任何优化 1600ms
#include<bits/stdc++.h>
using namespace std;
//input b y bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N) for(int i=0;i<(N);i++)
#define CLR(A,v) memset(A,v,sizeof A)
#define inf 0x3f3f3f3f
//////////////////////////////////
#define N 20+9 int n,m;
int vis[N];
int a[N];
int q[N];
int dp[];
int cnt;
int maxx; void dp1()
{
CLR(dp,);
dp[]=;
int cnt=;
rep(i,,n)
if(vis[i])
{
repp(j,,)
if(dp[j]&&!dp[j+a[i]])dp[j+a[i]]=,cnt++;
}
maxx=max(maxx,cnt);
} void dfs(int cur,int num)
{
if(num>n-m)return ;
if(num==n-m)
{
dp1();
return ;
}
rep(i,cur,n)
if(!vis[i])
{
vis[i]=;
dfs(i+,num+);
vis[i]=;
}
return ;
} int main()
{
RII(n,m);
rep(i,,n)
RI(a[i]); maxx=;
dfs(,);
cout<<maxx;
return ;
}
加一个dp上界的优化 950ms
#include<bits/stdc++.h>
using namespace std;
//input b y bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N) for(int i=0;i<(N);i++)
#define CLR(A,v) memset(A,v,sizeof A)
#define inf 0x3f3f3f3f
//////////////////////////////////
#define N 20+9 int n,m;
int vis2[];
int vis[N];
int a[N];
int q[N];
int dp[];
int cnt;
int tot;
int maxx; void dp1()
{
CLR(dp,);
dp[]=;
int cnt=;
rep(i,,n)
if(vis[i])
{
repp(j,tot,)
if(dp[j]&&!dp[j+a[i]])dp[j+a[i]]=,cnt++;
}
maxx=max(maxx,cnt);
} void dfs(int cur,int num)
{
if(num>n-m)return ;
if(num==n-m)
{
dp1();
return ;
}
rep(i,cur,n)
if(!vis[i])
{
vis[i]=;
dfs(i+,num+);
vis[i]=;
}
return ;
} int main()
{
RII(n,m);
tot=;
rep(i,,n)
RI(a[i]),tot+=a[i]; maxx=;
dfs(,);
cout<<maxx;
return ;
}
再次上界优化 400ms!!!!
#include<bits/stdc++.h>
using namespace std;
//input b y bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N) for(int i=0;i<(N);i++)
#define CLR(A,v) memset(A,v,sizeof A)
#define inf 0x3f3f3f3f
//////////////////////////////////
#define N 20+9
int n,m;
int vis[N];
int a[N];
int dp[];
int cnt;
int maxx; void dp1()
{
CLR(dp,);
dp[]=;
int cnt=;
int tot=;
rep(i,,n)
if(vis[i])
{
repp(j,tot,)
if(dp[j]&&!dp[j+a[i]])dp[j+a[i]]=,cnt++;
tot+=a[i];
}
maxx=max(maxx,cnt);
} void dfs(int cur,int num)
{
if(num>n-m)return ;
if(num==n-m)
{
dp1();
return ;
}
rep(i,cur,n)
if(!vis[i])
{
vis[i]=;
dfs(i+,num+);
vis[i]=;
}
return ;
} int main()
{
RII(n,m);
rep(i,,n)
RI(a[i]); maxx=;
dfs(,);
cout<<maxx;
return ;
}
P1441 砝码称重 DFS回溯+DP的更多相关文章
- 洛谷P1441 砝码称重(搜索,dfs+dp)
洛谷P1441 砝码称重 \(n\) 的范围为 \(n \le 20\) ,\(m\) 的范围为 \(m \le 4\) . 暴力遍历每一种砝码去除情况,共有 \(n^m\) 种情况. 对于剩余砝码求 ...
- 洛谷P1441 砝码称重(搜索,dfs+bitset优化)
洛谷P1441 砝码称重 \(n\) 的范围为 \(n \le 20\) ,\(m\) 的范围为 \(m \le 4\) . 暴力遍历每一种砝码去除情况,共有 \(n^m\) 种情况. 对于剩余砝码求 ...
- 7行代码解决P1441砝码称重(附优化过程)
先贴上最终代码感受一下: #include <bits/stdc++.h> using namespace std; int i, N, M, wi[21], res = 0; int m ...
- 洛谷P1441 砝码称重
P1441 砝码称重 题目描述 现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0). 输入输出格式 输入格式: 输入文件weight.in ...
- P1441 砝码称重(搜索+队列dp)
题目链接:传送门 题目大意: 给你n个砝码ai,从中去掉m个后求最多的砝码可表示的重量. n≤20,m≤4,m<n,ai≤100. 思路: 用dfs搜掉m个砝码,然后用队列dp跑出答案,维护答案 ...
- [P1441]砝码称重 (搜索+DP)
对于我这种蒟蒻,是很不错的一题了. dfs搜索当前状态 满足时DP 比较坑的地方就是起始的地方 我一开始从1开始,搜索写的是从0开始. 后来就统一用0开始的了. #include<bits/st ...
- 洛谷 P1441 砝码称重
题目描述 现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0). 输入输出格式 输入格式: 输入文件weight.in的第1行为有两个整数n ...
- P1441 砝码称重
题目描述 现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0). 输入输出格式 输入格式: 输入文件weight.in的第1行为有两个整数n ...
- [Luogu] P1441 砝码称重
题目描述 现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0). 题目分析 因为读错题WAWA大哭. 先dfs枚举选的砝码,满足条件时进行d ...
随机推荐
- java使用spark/spark-sql处理schema数据
1.spark是什么? Spark是基于内存计算的大数据并行计算框架. 1.1 Spark基于内存计算 相比于MapReduce基于IO计算,提高了在大数据环境下数据处理的实时性. 1.2 高容错性和 ...
- Laravel 怎么使用资源控制器delete方法
### 在视图上,想删除某个数据,而控制器是使用了resources controller的 那么在删除数据的时候,还是有些需要注意的地方 ### 视图上: <a href="java ...
- 【原创】大叔问题定位分享(32)mysql故障恢复
mysql启动失败,一直crash,报错如下: 2019-03-14T11:15:12.937923Z 0 [Note] InnoDB: Uncompressed page, stored check ...
- vue 上实现无缝滚动播放文字系统公告
首先实现效果,当时的需求做的系统公告框设定一个宽度,超宽滚动播放,没超宽则静态展示,有了需求,想了下实现原理,最开始打算js更改字体内容的方式,但是想了下感觉会有点麻烦,想起之前做了表格的左侧边固定, ...
- 分布式系统的一致性协议之 2PC 和 3PC
在分布式系统领域,有一个理论,对于分布式系统的设计影响非常大,那就是 CAP 理论,即对于一个分布式系统而言,它是无法同时满足 Consistency(强一致性).Availability(可用性) ...
- ORACLE 字段AES算法加密、解密
ORACLE 字段AES算法加密.解密(解决中文乱码问题)2014年02月12日 17:13:37 华智互联 阅读数:97971.加解密函数入口 CREATE OR REPLACE FUNCTION ...
- 10分钟了解Android的Handler机制
Handler机制是Android中相当经典的异步消息机制,在Android发展的历史长河中扮演着很重要的角色,无论是我们直接面对的应用层还是FrameWork层,使用的场景还是相当的多.分析源码一探 ...
- Redis的消息发布和订阅
Redis的消息发布和订阅 Author:SimpleWu GitHub-redis 什么是消息发布和订阅? Redis 发布订阅(pub/sub)是一种进程间的消息通信模式: 发送者(pub)发送消 ...
- django----常用功能
request.path_info 获取url地址
- Imperial roads 非严格次小生成树
cf测评姬比uva快了五倍... /* 不管这条边是不是在mst上,直接跑lca求出路径上的最大边w即可 ans=mst-w+dist(u,v) */ #include<bits/stdc++. ...