题目描述

现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0)。

请注意,砝码只能放在其中一边。

输入输出格式

输入格式:

输入文件weight.in的第1行为有两个整数n和m,用空格分隔

第2行有n个正整数a1,a2,a3,……,an,表示每个砝码的重量。

输出格式:

输出文件weight.out仅包括1个整数,为最多能称量出的重量数量。

输入输出样例

输入样例#1: 复制

3 1
1 2 2
输出样例#1: 复制

3

说明

【样例说明】

在去掉一个重量为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的更多相关文章

  1. 洛谷P1441 砝码称重(搜索,dfs+dp)

    洛谷P1441 砝码称重 \(n\) 的范围为 \(n \le 20\) ,\(m\) 的范围为 \(m \le 4\) . 暴力遍历每一种砝码去除情况,共有 \(n^m\) 种情况. 对于剩余砝码求 ...

  2. 洛谷P1441 砝码称重(搜索,dfs+bitset优化)

    洛谷P1441 砝码称重 \(n\) 的范围为 \(n \le 20\) ,\(m\) 的范围为 \(m \le 4\) . 暴力遍历每一种砝码去除情况,共有 \(n^m\) 种情况. 对于剩余砝码求 ...

  3. 7行代码解决P1441砝码称重(附优化过程)

    先贴上最终代码感受一下: #include <bits/stdc++.h> using namespace std; int i, N, M, wi[21], res = 0; int m ...

  4. 洛谷P1441 砝码称重

    P1441 砝码称重 题目描述 现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0). 输入输出格式 输入格式: 输入文件weight.in ...

  5. P1441 砝码称重(搜索+队列dp)

    题目链接:传送门 题目大意: 给你n个砝码ai,从中去掉m个后求最多的砝码可表示的重量. n≤20,m≤4,m<n,ai≤100. 思路: 用dfs搜掉m个砝码,然后用队列dp跑出答案,维护答案 ...

  6. [P1441]砝码称重 (搜索+DP)

    对于我这种蒟蒻,是很不错的一题了. dfs搜索当前状态 满足时DP 比较坑的地方就是起始的地方 我一开始从1开始,搜索写的是从0开始. 后来就统一用0开始的了. #include<bits/st ...

  7. 洛谷 P1441 砝码称重

    题目描述 现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0). 输入输出格式 输入格式: 输入文件weight.in的第1行为有两个整数n ...

  8. P1441 砝码称重

    题目描述 现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0). 输入输出格式 输入格式: 输入文件weight.in的第1行为有两个整数n ...

  9. [Luogu] P1441 砝码称重

    题目描述 现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0). 题目分析 因为读错题WAWA大哭. 先dfs枚举选的砝码,满足条件时进行d ...

随机推荐

  1. Day8--------------RPM包管理

    nginx.tar.gz:源码,编译安装 RPM:redhat package manage,二进制 增.删.查 1.增 package------>ls|less------------> ...

  2. ELK Packetbeat 部署指南

    http://www.ttlsa.com/elk/elk-packetbeat-deployment-guide/

  3. CSS rem长度单位

    1. 概述 1.1 说明 rem是css3中新增的一个单位属性(font size of the root element),根据页面的根节点(html)的字体大小进行转换的单位,通过此单位属性可以进 ...

  4. Android中播放音乐的几种方式

    前言 前几天一直在研究RxJava2,也写了记录了几篇博客,但因为工作任务原因,需要研究音频相关的知识,暂时放下Rxjava,本文的demo中,MediaPalyer 部分使用RxJava编写一点逻辑 ...

  5. ADO.NET连接字符串大全---各种数据库的连接字符串

    ADO.NET连接字符串大全 ADO.NET连接字符串 名称 ADO.NET连接字符串 说明 ADO.NET连接字符串:SQL Server,SQL Server 2005,ACCESS,Oracle ...

  6. leetcode(js)算法605之种花问题

    假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去. 给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花 ...

  7. <<人月神话>>阅读体会(一)

    第一次听说人月神话还是在大一上学期的导论课那会儿,那会儿好像就已经确定了自己要学软件,于是就去问王建民老师能不能给我推荐几本软件工程方面的书,我想要提前自己学学,以为老师会给我推荐一些某种语言类的学习 ...

  8. mongo 的导入和导出

    1.导出工具:mongoexport     1.概念:         mongoDB中的mongoexport工具可以把一个collection导出成JSON格式或CSV格式的文件.可以通过参数指 ...

  9. Python基础之常用模块

    一.time模块 1.时间表达形式: 在Python中,通常有这三种方式来表示时间:时间戳.元组(struct_time).格式化的时间字符串: 1.1.时间戳(timestamp) :通常来说,时间 ...

  10. linux下安装pip与pip安装

    在执行脚本的时候,说有库找不到 pip安装的时候说不认识pip 安装pip 使用脚本安装和升级pip wget https://bootstrap.pypa.io/get-pip.py 运行脚本pyt ...