洛谷 P1156 垃圾陷阱 谈论剪枝,非满分
这是一个91分的非dp代码(是我太弱)
剪枝八五个(实际上根本没那么多,主要是上课装逼,没想到他们dp水过去了),不过我的思路与dp不同;
1.层数到达i+1,return 这个必须有
2.当前剩余生命吃不到垃圾,return,必须有
3.当前答案比目前最优解大,return
4.到达第i个点,剩余相同的生命,但是比以前走的短,return
5.到达第t时间,剩余相同生命,同上return
6.增加一个上限阀值,这样目前的解很接近最正确答案(但是第二和5个数据点貌似专门在卡这个(是我太弱)
7.做两次dfs,第一次先贪存货时间久,第二次贪升高(玄学的是如果调换就会只有45)
8.烧香
尤其要注意的是,这道题并没有保证输入数据按从小到大来,因此你还需要对输入的数据排遍序!
代码一:
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<fstream>
using namespace std;
int life=;
int d1[][],d2[][]; //d1指的是
int n,d;
struct junk{
int h,t,l;
};
int cmp(junk a,junk b)
{
return a.t<b.t;
}
int ans=0x3ffffff;
int lifenow=;
int ts=;
junk f[];
int bj(int t)
{
ans=min(ans,t);
ts=;
}
int bj2(int l)
{
lifenow=max(l,lifenow);
}
long long u;
long long p=0x2FFFFFF-;
void dfs1(int i,int dep,int l,int t)
{
u++;
if(u>p/) return ;
bj2(l);
if(t>ans) return ;
if(l<f[i].t) return ;
if(dep>=d)
{
bj(t);
return ;
}
if(i>n) return ;
if(d1[i][l]>dep||d2[t][l]>dep) return ;
d1[i][l]=dep;
d2[t][l]=dep;
dfs1(i+,dep,l+f[i].l,f[i].t);
dfs1(i+,dep+f[i].h,l,f[i].t);
if(u>p/) return ;
}
void dfs2(int i,int dep,int l,int t)
{
u++;
if(u>p) return ;
bj2(l);
if(t>ans) return ;
if(l<f[i].t) return ;
if(dep>=d)
{
bj(t);
return ;
}
if(i>n) return ;
if(d1[i][l]>dep||d2[t][l]>dep) return ;
d1[i][l]=dep;
d2[t][l]=dep;
dfs2(i+,dep+f[i].h,l,f[i].t);
dfs2(i+,dep,l+f[i].l,f[i].t);
if(u>p) return ;
}
int main()
{
cin>>d>>n;
int h=;
int i,j,k;
for(i=;i<=n;i++)
cin>>f[i].t>>f[i].l>>f[i].h;
sort(f+,f+n+,cmp);
dfs1(,,,);
dfs2(,,,);
if(ans==||lifenow==)
{
cout<<;
return ;
}//骗分
if(ts)
cout<<ans;
else cout<<lifenow;
return ;
}
/*
\ | /
\ | /
\ | /
\ | /
\ | /
\|/
Accept!
0ms/0kb
*/
另外,我们发现,dfs的复杂度太高主要是有太多次优借刷新,我们如果将d1,d2改变,让他变成每个点每种情况的的dfs到达次数,那么,我们可以通过来限制某个情况被刷新的次数来优化时间复杂度,假设每个点被限制t次,t是可以极小的,大约为100,(*1e7 / gt≈800)t=100时,时间大大优化了,可以自己去测一下,大约为15ms,比一般的dfs优化了不知道多少.(还是91分,不知道剩下那个数据有多毒瘤)
代码2:
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<fstream>
using namespace std;
int life=;
int d1[][],d2[][];
int n,d;
struct junk{
int h,t,l;
};
int cmp(junk a,junk b)
{
return a.t<b.t;
}
int ans=0x3ffffff;
int lifenow=;
int ts=;
junk f[];
int bj(int t)
{
ans=min(ans,t);
ts=;
}
int bj2(int l)
{
lifenow=max(l,lifenow);
}
long long u;
long long p=0x2FFFFFF-;
void dfs1(int i,int dep,int l,int t)
{
u++;
if(u>p/) return ;
bj2(l);
if(t>ans) return ;
if(l<f[i].t) return ;
if(dep>=d)
{
bj(t);
return ;
}
if(i>n) return ;
if(d1[i][l]>||d2[t][l]>) return ;
d1[i][l]++;
d2[t][l]++;
dfs1(i+,dep,l+f[i].l,f[i].t);
dfs1(i+,dep+f[i].h,l,f[i].t);
if(u>p/) return ;
}
}
int main()
{
cin>>d>>n;
int h=;
int i,j,k;
for(i=;i<=n;i++)
cin>>f[i].t>>f[i].l>>f[i].h;
sort(f+,f+n+,cmp);
dfs1(,,,);
if(ts)
cout<<ans;
else cout<<lifenow;
return ;
}
洛谷 P1156 垃圾陷阱 谈论剪枝,非满分的更多相关文章
- 洛谷 P1156 垃圾陷阱
2016-05-31 09:54:03 题目链接 :洛谷 P1156 垃圾陷阱 题目大意: 奶牛掉坑里了,给定坑的深度和方块的个数,每个方块都可以垫脚或者吃掉维持生命(初始为10) 若可以出来,求奶牛 ...
- 洛谷——P1156 垃圾陷阱
P1156 垃圾陷阱 题目描述 卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中.“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2 \le D \le 100)D(2≤D ...
- 洛谷 P1156 垃圾陷阱 (01背包拓展)(好题!!)
这真是一道好题目 学到了很多 一开始感觉吃或者不吃会有后效性 然后看到洛谷的题解,直接把这个有后效性的部分当作dp的维度和值 因为这个垃圾可以堆或者不堆,所以这个很像01背包, 但是加了非常多的限制条 ...
- 洛谷P1156 垃圾陷阱[背包DP]
题目描述 卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中.“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2<=D<=100)英尺. 卡门想把垃圾堆起来,等到 ...
- 洛谷P1156 垃圾陷阱
动规仍然是难关啊 题目描述 卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中.“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2<=D<=100)英尺. 卡门想 ...
- 洛谷P1156 垃圾陷阱【线性dp】
题目:https://www.luogu.org/problemnew/show/P1156 题意: 每一个垃圾投放时间是t,可以堆的高度是h,如果吃掉可以增加的生命值是f. 给定g个垃圾,初始生命值 ...
- 洛谷P1156 垃圾陷阱 dp
正解:dp 解题报告: 这儿是传送门! 话说最近怎么神仙们都开始狂刷dp,,,感觉今天写了好多dp的题解的样子?(也就三四道其实× 然后这题,首先看到要么吃要么堆起来就会想到01背包趴?然后就考虑设方 ...
- 洛谷 P1156 垃圾陷阱 题解
题目传送门 dp+排序+01背包 就完事了??? 貌似就是这样的 代码: //dp 排序 01背包 #include<iostream> #include<cstdio> #i ...
- 洛谷$1156$ 垃圾陷阱 $dp$
\(Sol\) \(f_{i,j}\)前\(i\)个垃圾,能活到时间\(j\)的最高垃圾高度.\(t_i\)表示第\(i\)个垃圾掉落的时间,\(g_i\)表示吃垃圾\(i\)能维持的时间,\(h_i ...
随机推荐
- ssm框架下实现文件上传
1.由于ssm框架是使用Maven进行管理的,文件上传所需要的jar包利用pom.xml进行添加,如下所示: <properties> <commons-fileupload.v ...
- ADB over Wi-Fi
ADB over Wi-Fi 1.root $adb root 2.设置tcp端口并重启tcpip服务 $adb shell setprop persist.adb.tcp.port &&am ...
- Eclipse安装jad反编译插件(在线安装)
Help→Eclipse Marketplace→Find→jad 然后等安装完成重启eclipse即可
- HDU 1220 B - Cube
http://acm.hdu.edu.cn/showproblem.php?pid=1220 一开始的做法是,先暴力算出一个面,就是n * n的面,能有多少对.记作face 然后从上开始算下来,最上一 ...
- NFS与AutoNFS实例
NFS概述: NFS,是Network File System的简写,即网络文件系统.网络文件系统是FreeBSD支持的文件系统中的一种,也被称为NFS. NFS允许一个系统在网络上与他人共享目录和文 ...
- qconshanghai2015
http://2015.qconshanghai.com/schedule 大会日程 2015年10月15日 星期四 08:30 开场致辞 地点 光大宴会厅 专题 主题演讲 数据分析与移动开发工具 ...
- 基于ABP的Easyui admin framework正式开放源代码
下载&反馈:http://www.webplus.org.cn v1.0 (2016/9/21) EF6+MVC5+API2+Easyui1.4.2开发 后台管理不使用iframe,全ajax ...
- AJPFX的内存管理小结
管理范围:任何继承于 NSObject的对象原理:每一个对象都有引用计数器当使用alloc new 和 copy创建对象时引用计数器被设置为1给对象发送一条retain消息 ,引用计数器加1 ...
- PKU_campus_2018_H Safe Upper Bound
思路: 题目链接http://poj.openjudge.cn/practice/C18H/ 用2147483647除以最大素因子. 这里用了Pollard_rho因子分解算法,模板参考了http:/ ...
- P3372 【模板】线段树 1 区间查询与区间修改
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个 ...