伪紫题p5194 天平(dfs剪枝)
2024-09-01 16:44:09
这题作为一个紫题实在是过分了吧。。。
绿的了不起了。
——————————————————————————
看题第一眼,01背包无误。2min打好一交全屏紫色(所以这就是这题是紫色的原因233?)
re原因:即使压掉一维,dp数组的下标也有1e10 * 2 以上,不MLE就不错了。
肯定是动态规划一类的东西了。根据题目这一句话:这一行中从第3个砝码开始,每个砝码的质量至少等于前面两个砝码(也就是质量比它小的砝码中
质量最大的两个)的质量的和。是不是很像斐波那契?于是推出来:n的真实值其实也很小,大约在30左右吧。但是朴素搜索也会原地爆裂。
怎么剪枝呢?大约有三个剪枝。
#1:输入的时候,如果当前的重量已经大于限制了,就停止,把砝码总数重新定义。
#2:题目里所有的砝码都是单调递增的,所以不会出现去掉前面某一个砝码然后取后面一个来找到最大值(可能表述有些问题,或者我根本理解错了,欢迎指正)所以维护一个前缀和,如果这个能拿,就把前面的全都拿了(或者说当前的砝码一定大于等于前面所有的砝码重量和)
#3:因为找最大,所以从后往前搜索。
大概就是这样。
#include<bits/stdc++.h>
//变量解释:a数组存题目给定值,b数组为前缀和数组,n为砝码数量,m为限制重量
using namespace std;
const int maxn=500005;
int n,m;
long long ans,a[maxn],b[maxn];
void dfs(int now,long long ma)//当前砝码序号和最大值
{
if(ma+b[now]<=ans)//剪枝#2
return;
ans=max(ans,ma);
for(int i=now;i;i--)//剪枝#3
if(ma+a[i]<=m)
dfs(i-1,ma+a[i]);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
if(a[i]>m)
{
n=i-1;//剪枝#1
break;
}
b[i]=b[i-1]+a[i];//剪枝#2
}
dfs(n,0);
printf("%lld",ans);
return 0;
}
应该就是这样吧。。。
(完)
最新文章
- 绘制扇形效果线条小Bug解决
- Unity学习疑问记录之触摸点坐标
- startActivity跳转失败而且没有异常信息
- spring第一课,beans配置(中)——自动装配
- 安装初始化mysql后,默认几个库介绍
- 四则运算 Day1
- android-监听网络状态
- 火狐Firefox 浏览器 onblur() 并且alert()时文本被选中问题
- Netty4.X 学习(一)
- linux下ssh端口的修改和登录
- python中的可变与不可变对象
- [RPC Fault faultString=";Cannot invoke method &#39;saveOrUpdate&#39;."; faultCode=";Server.ResourceUnavailable";
- 洛谷 P3797 妖梦斩木棒
- 7.Flask文件上传
- Windows Server 2012 配置远程桌面帐户允许多用户同时登录
- Jenkins自动部署增加http状态码校验
- 使用curl自动签到smzdm
- datagrid数据表格当数据为0的时候页面不显示数据
- Java使用 SFTP实现文件上传下载
- URAL 1698