洛谷 1441 砝码称重 搜索+DP 解题报告
来源:互联网 发布:cs1.6中文版for mac 编辑:程序博客网 时间:2024/05/22 15:09
题目描述
现有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。
思路
首先,对于这种状态类型的题目,数据范围比较小,我们可以dfs暴力枚举每一种情况,然后在每一种情况确定下来过后,对其进行01背包的操作。
通过dfs过程找到一种状态以后,求出使用当前留下的这些砝码可以凑出多少个不同的重量,我们通过dp解决这个问题。
定义dp[i][j]为当前选取到了第j个砝码,如果通过之前的砝码可以称量出重量i那么dp[i][j]的值为1。
状态转移方程为:
初始状态为
最后dp[i][n]中1的个数就是通过这些砝码可以计算出的重量值。
但是因为只求每次的最大值,所以只用一维的数组滚动,每次清零就好了。可以只定义一个dp[i]数组,从而降低了时间空间复杂度,但是要注意此时内层循环倒序。(想想为什么)
这里要注意,我在dfs的时候第一次只是
代码
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>#include<vector>using namespace std;const int N=20+2;const int M=2000+5;int n,m,w[N],dp[M],flag[N],top,ans=0,tot;void work01(){ memset(dp,0,sizeof(dp)); dp[1]=1;tot=0;top=1; for (int i=1;i<=n;i++) { if (flag[i]==1) continue; for (int j=top;j>=0;j--) if (dp[j]&&!dp[j+w[i]]) dp[j+w[i]]=1,tot++; top+=w[i]; }//滚动 ans=max(ans,tot);}void dfs(int u,int now){ if (now>m) return ; if (u==n+1) {if (now==m) work01();return ;} dfs(u+1,now); flag[u]=1; dfs(u+1,now+1); flag[u]=0; } int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&w[i]); dfs(1,0); printf("%d\n",ans); return 0;}/*3 11 2 2*/
阅读全文
0 0
- 洛谷 1441 砝码称重 搜索+DP 解题报告
- LuoguP1441 砝码称重 解题报告【搜索+背包型DP】
- 砝码称重 解题报告
- 砝码称重 解题报告
- 蓝桥杯 砝码称重 递归 解题报告
- 砝码称重(dp)
- 砝码称重问题【dp】
- ssl1072-砝码称重【dp练习】
- 洛谷 P1441 砝码称重--搜索位运算优化
- POJ 1702 解题报告——Eva's Balance:用砝码为物体称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- Java并发编程:ThreadLocal
- Python: PS 滤镜--旋涡特效
- PAT考试乙级1001(C语言实现)
- shell中函数的使用方法
- IO流--字符流(补充)
- 洛谷 1441 砝码称重 搜索+DP 解题报告
- 常用颜色
- C#版OPC Client经验总结
- 死锁产生的原因和解决办法
- 单机列表 网络
- Intellij IDEA 创建 Maven SpringMVC 项目的方法
- 关于Oracle、Weblogic等分类的创建
- Wannafly模拟赛3
- 成绩