题目描述

约翰有一架用来称牛的体重的天平.与之配套的是N(1≤N≤1000)个已知质量的砝码(所有砝码质量的数值都在31位二进制内).每次称牛时,他都把某头奶牛安置在天平的某一边,然后往天平另一边加砝码,直到天平平衡,于是此时砝码的总质量就是牛的质量(约翰不能把砝码放到奶牛的那边,因为奶牛不喜欢称体重,每当约翰把砝码放到她的蹄子底下,她就会尝试把砝码踢到约翰脸上).天平能承受的物体的质量不是无限的,当天平某一边物体的质量大于C(1≤C<2^30)时,天平就会被损坏. 砝码按照它们质量的大小被排成一行.并且,这一行中从第3个砝码开始,每个砝码的质量至少等于前面两个砝码(也就是质量比它小的砝码中质量最大的两个)的质量的和. 约翰想知道,用他所拥有的这些砝码以及这架天平,能称出的质量最大是多少.由于天平的最大承重能力为C.他不能把所有砝码都放到天平上.

现在约翰告诉你每个砝码的质量,以及天平能承受的最大质量.你的任务是选出一些砝码,使它们的质量和在不压坏天平的前提下是所有组合中最大的.

输入格式

第1行:两个用空格隔开的正整数N和C.

第2到N+1行:每一行仅包含一个正整数,即某个砝码的质量.保证这些砝码的质量是一个不下降序列

输出格式

一个正整数,表示用所给的砝码能称出的不压坏天平的最大质量.


第一眼想用背包来做这题,然而数据太大了......

注意题中指明了砝码重量最慢的情况呈斐波那契式增长。通过输出斐波那契数列发现当n=45时Fib[n]就大于1e9了。所以这题的n实际上也就50的规模......

既然动规的数组存不下,又没(lan)想(de)到(xiang)其它算法,先打个爆搜下去。火字旁细节了

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #define maxn 1001
  5. using namespace std;
  6. int a[maxn];
  7. int m,n;
  8. long long ans,c[maxn];
  9. inline int read(){
  10. register int x(0),f(1); register char c(getchar());
  11. while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
  12. while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
  13. return x*f;
  14. }
  15. void dfs(int d,long long now){
  16. if(d>n){ ans=max(ans,now); return; }
  17. if(now+a[d]<=m) dfs(d+1,now+a[d]);//选
  18. dfs(d+1,now);//不选
  19. }
  20. int main(){
  21. n=read(),m=read();
  22. for(register int i=1;i<=n;i++) a[i]=read();
  23. for(register int i=1;i<=n;i++) c[i]=c[i-1]+a[i];
  24. dfs(1,0);
  25. printf("%lld\n",ans);
  26. return 0;
  27. }

然后考虑剪枝。首先我们可以倒着枚举砝码,这样产生的搜索树就会小很多;

然后假设当前的答案为ans,最多的情况就是从当前位开始把后面的全部都选上。如果后面的砝码总重加上当前的重量都要小于等于ans的话那就没必要往下搜了。

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #define maxn 1001
  5. using namespace std;
  6. int a[maxn];
  7. int m,n;
  8. long long ans,c[maxn];
  9. inline int read(){
  10. register int x(0),f(1); register char c(getchar());
  11. while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
  12. while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
  13. return x*f;
  14. }
  15. void dfs(int d,long long now){
  16. if(d>n){ ans=max(ans,now); return; }
  17. if(now+c[n]-c[d-1]<=ans) return;//最优性剪枝
  18. if(now+a[d]<=m) dfs(d+1,now+a[d]);
  19. dfs(d+1,now);
  20. }
  21. int main(){
  22. n=read(),m=read();
  23. for(register int i=n;i>=1;i--) a[i]=read();//倒着枚举
  24. for(register int i=1;i<=n;i++) c[i]=c[i-1]+a[i];
  25. dfs(1,0);
  26. printf("%lld\n",ans);
  27. return 0;
  28. }

[Usaco2005 Dec]Scales 天平的更多相关文章

  1. bzoj1673[Usaco2005 Dec]Scales 天平*

    bzoj1673[Usaco2005 Dec]Scales 天平 题意: n个砝码,每个砝码重量大于前两个砝码质量和,天平承重为c,求天平上最多可放多种的砝码.n≤1000,c≤2^30. 题解: 斐 ...

  2. bzoj:1673 [Usaco2005 Dec]Scales 天平

    Description Farmer John has a balance for weighing the cows. He also has a set of N (1 <= N <= ...

  3. 【BZOJ】1673: [Usaco2005 Dec]Scales 天平(dfs背包)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1673 bzoj翻译过来的c<=230不忍吐槽......................... ...

  4. BZOJ 1673 [Usaco2005 Dec]Scales 天平:dfs 启发式搜索 A*搜索

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1673 题意: 有n个砝码(n <= 1000),重量为w[i]. 你要从中选择一些砝 ...

  5. bzoj 1673: [Usaco2005 Dec]Scales 天平【dfs】

    真是神奇 根据斐波那契数列,这个a[i]<=c的最大的i<=45,所以直接搜索即可 #include<iostream> #include<cstdio> usin ...

  6. 【BZOJ1672】[Usaco2005 Dec]Cleaning Shifts 清理牛棚 动态规划

    [BZOJ1672][Usaco2005 Dec]Cleaning Shifts Description Farmer John's cows, pampered since birth, have ...

  7. 【BZOJ1671】[Usaco2005 Dec]Knights of Ni 骑士 BFS

    [Usaco2005 Dec]Knights of Ni 骑士 Description  贝茜遇到了一件很麻烦的事:她无意中闯入了森林里的一座城堡,如果她想回家,就必须穿过这片由骑士们守护着的森林.为 ...

  8. BZOJ1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚

    1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 414  Solved: ...

  9. BZOJ1671: [Usaco2005 Dec]Knights of Ni

    1671: [Usaco2005 Dec]Knights of Ni Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 175  Solved: 107[Su ...

随机推荐

  1. CSS3全览_动画+滤镜

    CSS3全览_动画+滤镜 目录 CSS3全览_动画+滤镜 1. 列表和生成的内容 2. 变形 3. 过渡 4. 动画 5. 滤镜, 混合, 裁剪和遮罩 6. 针对特定媒体的样式 作者: https:/ ...

  2. js上 十三、函数初步-2

    13-1.函数的参数 函数的本质: ü 函数的作用,代码重用,编写一个函数,就是为了解决一类问题. ü 函数每次调用,都有一个结果,那么结果和什么相关呢?y = x , y = x2,y = sin( ...

  3. react第十五单元(react路由的封装,以及路由数据的提取)

    第十五单元(react路由的封装,以及路由数据的提取) #课程目标 熟悉react路由组件及路由传参,封装路由组件能够处理路由表 对多级路由能够实现封装通用路由传递逻辑,实现多级路由的递归传参 对复杂 ...

  4. 二、Electron + Webpack + Vue 搭建开发环境及打包安装

    目录 Webpack + Vue 搭建开发环境及打包安装 ------- 打包渲染进程 Electron + Webpack  搭建开发环境及打包安装 ------- 打包主进程 Electron + ...

  5. 1-解决java Scanner出现 java.util.NoSuchElementException

    起因:在函数中新建scanner对象,然后多次调用此方法出现上述异常 原因:Scanner(system.in)在Scanner中接受的是键盘 输入,当调用close()方法时 Scanner的关闭会 ...

  6. PHP可变变量特性

    可变变量 有时候使用可变变量名是很方便的.就是说,一个变量的变量名可以动态的设置和使用.一个普通的变量通过声明来设置,例如: <?php$a = 'hello';?> 一个可变变量获取了一 ...

  7. Appium App UI 自动化测试理论知识

    (一)App自动化测试背景 随着移动终端的普及,手机应用越来越多,也越来越重要.App的回归测试用例数量越来越多,全量回归也越来越消耗时间.另外移动端碎片化严重(碎片化:兼容性测试,手机品牌多样.An ...

  8. spring依赖注入的方式(一)

    为了方便类的管理,spring提供了依赖注入的思想:类的实例化不由程序员控制,而是交给sprig容器进行管理. spring提供了多种类型的注入方式---注解.xml注入: 1  注解注入 有两种:@ ...

  9. 将两个ListMap中同下标的map去重合并

    public static void main(String[] args) { Map<String,Object> oneMap = new HashMap<>(); on ...

  10. 从最长公共子序列问题理解动态规划算法(DP)

    一.动态规划(Dynamic Programming) 动态规划方法通常用于求解最优化问题.我们希望找到一个解使其取得最优值,而不是所有最优解,可能有多个解都达到最优值. 二.什么问题适合DP解法 如 ...