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 ...
随机推荐
- HTML网页背景图很长要有滚动条滑动
1 前言 由于网页背景图非常长,然后会出现只显示当前页面,后面部分看不到,也不能滑动,开始以为不能滑动应该是没有加overflow-y: auto(scroll),结果加上去也是无效的. 2 代码 & ...
- [nodejs]er_bad_field_error NaN in where clause
1 前言 nodejs 运行时,出现以下情况er_bad_field_error NaN in where clause. 2 分析 原来是userid = NAN传进来了,生成userid时出错了. ...
- Go代码重构:23倍的性能爆增
几周前,我读了一篇名为“ Good Code vs Go Code中的错误代码 ”的文章,作者指导我们逐步完成实际业务用例的重构. 本文的重点是将“坏代码”转变为“良好代码”:更具惯用性,更易读,利用 ...
- 解决Navicat连接MySQL总是报错1251的方法
今天下了个 MySQL8.0,发现Navicat连接不上,总是报错1251: 原因是MySQL8.0版本的加密方式和MySQL5.0的不一样,连接会报错. 试了很多种方法,终于找到一种可以实现的: 更 ...
- Windows Server 2016 + SCO 2016 安装及配置介绍
Windows Server 2016 + SCO 2016 安装及配置介绍 高文龙关注1人评论6332人阅读2017-02-26 23:23:02 Windows Server 2016 + SCO ...
- Confluence 6 中修改默认的表现和内容
Confluence 构建了一些有用的默认设置,这些设置能够让第一次访问使用 Confluence 系统的用户更好的了解系统.同时默认的内容将新空间和其他区域放置在 Confluence 中. Con ...
- 《剑指offer》 二叉树的镜像
本题来自<剑指offer>二叉树的镜像 题目: 操作给定的二叉树,将其变换为源二叉树的镜像. 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 ...
- java报错:The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files
看包的路径是否对对:比如这样不对(...src/object/obietc) 其它解决方法转载: https://www.cnblogs.com/yadongliang/p/5918228.html ...
- WampServer & XAMPP Configure with MariaDB and MySQL
第一部分补上次的一个问题 1.WampServer 3不支持的硬件格式 FAT3和 exFAT 他只能工作在NTFS的格式硬盘上. 不能在Windows XP上运行. 安装 WampServer 必须 ...
- cut sticks
问题 : cut sticks 时间限制: 1 Sec 内存限制: 128 MB 题目描述 George took sticks of the same length and cut them ra ...