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 ...
随机推荐
- 【原创】大数据基础之Presto(1)简介、安装、使用
presto 0.217 官方:http://prestodb.github.io/ 一 简介 Presto is an open source distributed SQL query engin ...
- 【原创】大数据基础之Airflow(2)生产环境部署airflow研究
一 官方 airflow官方分布式部署结构图 airflow进程 webserver scheduler flower(非必须) worker airflow缺点 scheduler单点 通过在sch ...
- 随机生成游戏用户昵称(nodejs版本)(含机器人头像,金币等)
1 前言 有时需要生成随机的用户(或机器人)昵称,头像,金币等,但又不想太生硬,可以现在网上爬一些常见昵称到文本中,然后读取出来,随机使用即可. 2 代码 var nickNameArr = []; ...
- 新建项目虚拟环境及pycharm配置
基本操作 查询已有的虚拟环境 workon 激活虚拟环境 workon 虚拟环境名 退出虚拟环境 deactivate 删除虚拟环境 rmvirtualenv 虚拟环境名 查看python版本检查 p ...
- DataGridView中进行增删改查
首先我们需要知道是在哪个数据库中的哪个表进行增删改查: 这就需要我们: 建立给连接服务器的类:(可以在方法类中建立) 建立一个对列名进行封装的类:方便数据之间的传接:(学到Linq-sql时这些就简便 ...
- ionic3 国际化
http://www.cnblogs.com/huangenai/p/6868173.html 按上面这个网站的步骤整一遍, 但是ionic3 会报错 所以 在 import { NgModule ...
- usrp使用
首先打开linux 输入uhd_find_divice gqrx
- java web----TCP/DUP 通信
服务端和单客户端通信 注意事项:如果服务端或者客户端采用read() 一个字节这种读取数据,只要另一方没有关闭连接,read是永远读取不到-1,会陷入死循环中: 解决方法:加上一个判断,程序员自己跳出 ...
- MySQL----数据库练习
一.多对多的正反向查询 class Class(models.Model): name = models.CharField(max_length=32,verbose_name="班级名& ...
- bzoj 1415
莫名互测题... 这题一看就是期望dp,可是不会转移,所以考试写50分暴力走人... #include <cstdio> #include <cmath> #include & ...