CF1430F Realistic Gameplay (贪心+DP)
朴素做法暴力DP,O(nk)过不去。。。


1 #include <cmath>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 #define N1 2005
6 #define ll long long
7 using namespace std;
8
9 int n,p;
10 int l[N1],r[N1],a[N1];
11 ll f[N1][N1];
12 ll linf=0x3f3f3f3f3f3fll;
13
14 int main()
15 {
16 freopen("a.txt","r",stdin);
17 scanf("%d%d",&n,&p);
18 for(int i=1;i<=n;i++) scanf("%d%d%d",&l[i],&r[i],&a[i]);
19 for(int i=0;i<=n;i++) for(int k=0;k<=p;k++) f[i][k]=linf;
20 f[0][p]=0; l[n+1]=r[n]+1;
21 for(int i=1;i<=n;i++)
22 {
23 for(int k=0;k<p;k++)
24 {
25 if(a[i]%p<=k)
26 {
27 if(a[i]/p<=r[i]-l[i])
28 {
29 f[i][k-a[i]%p]=f[i-1][k]+a[i]/p;
30 if(a[i]/p+1<=l[i+1]-l[i]) f[i][p]=min(f[i][p],f[i-1][k]+a[i]/p+1);
31 }
32 }
33 if(a[i]%p>k)
34 {
35 if(a[i]/p+1<=r[i]-l[i])
36 {
37 f[i][k+p-a[i]%p]=f[i-1][k]+a[i]/p+1;
38 if(a[i]/p+2<=l[i+1]-l[i]) f[i][p]=min(f[i][p],f[i-1][k]+a[i]/p+2);
39 }
40 }
41 }
42 if(a[i]%p)
43 {
44 if(a[i]/p<=r[i]-l[i])
45 {
46 f[i][p-a[i]%p]=f[i-1][p]+a[i]/p;
47 if(a[i]/p+1<=l[i+1]-l[i]) f[i][p]=min(f[i][p],f[i-1][p]+a[i]/p+1);
48 }
49 }else{
50 if(a[i]/p-1<=r[i]-l[i])
51 {
52 f[i][0]=f[i-1][p]+a[i]/p-1;
53 if(a[i]/p<=l[i+1]-l[i]) f[i][p]=min(f[i][p],f[i-1][p]+a[i]/p);
54 }
55 }
56
57 }
58 ll ans=linf;
59 for(int k=0;k<=p;k++) ans=min(ans,f[n][k]*p+p-k);
60 if(ans==linf) puts("-1"); else printf("%lld\n",ans);
61 return 0;
62 }
先考虑贪心这个过程
对于从i开始连续的几波,如果我们只进行不浪费子弹的换弹,我们都可以到达那些波,同时记录到达这些波换的弹夹数g[i][j],处理出这两个数组的时间是O(n),总时间O(n^2)
然后进行DP,f[i]记录答案,表示处理完前i-1波消耗的子弹数,那么f[i]可以由所有贪心到达i-1的点j转移过来,f[i]=min(f[j]+g[j][i-1]*p),注意如果i和i-1之间有间隙时间,是可以转移的
总结:贪心可以处理时间充裕的情况,而DP则用来求解必须满弹开始的情况
1 #include <cmath>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 #define N1 2005
6 #define ll long long
7 using namespace std;
8
9 int n,p;
10 int l[N1],r[N1],a[N1];
11 ll f[N1],g[N1][N1],Rem[N1];
12 bool ok[N1][N1];
13 ll linf=0x3f3f3f3f3f3fll;
14 int divup(int x,int y)
15 {
16 if(x%y) return x/y+1;
17 else return x/y;
18 }
19
20 int main()
21 {
22 // freopen("a.txt","r",stdin);
23 scanf("%d%d",&n,&p);
24 for(int i=1;i<=n;i++) scanf("%d%d%d",&l[i],&r[i],&a[i]);
25 int rem,cnt,tim,num;
26 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) g[i][j]=linf;
27 for(int i=2;i<=n;i++) f[i]=linf;
28 for(int i=1;i<=n;i++)
29 {
30 //greedy
31 num=divup(a[i],p);
32 if(num-1<=r[i]-l[i]) //start with full
33 {
34 g[i][i]=cnt=num, rem=num*p-a[i];
35 Rem[i]=rem;
36 if(num<=r[i]-l[i]) //supply if empty
37 {
38 ok[i][i]=1;
39 if(rem==0) rem=p, cnt++;
40 }
41 for(int j=i+1;j<=n;j++) //never throw away remaining bullets
42 {
43 if(rem>a[j]){
44 rem-=a[j], g[i][j]=cnt;
45 }else{
46 num=divup(a[j]-rem,p); //never reload between consecutive waves
47 if(num<=r[j]-l[j]) g[i][j]=cnt=cnt+num, rem=num*p+rem-a[j];
48 else{
49 break;
50 }
51 }
52 Rem[i]=rem;
53 if(num+1<=r[j]-l[j])
54 {
55 if(rem==0) rem=p, cnt++;//supply if empty
56 ok[i][j]=1;
57 }
58 }
59 }else{
60 puts("-1"); return 0;
61 }
62 }
63 f[1]=0;
64 for(int i=2;i<=n;i++)
65 {
66 //DP
67 for(int j=1;j<i;j++)
68 {
69 if(g[j][i-1]!=linf && (ok[j][i-1] || r[i-1]<l[i] ) )
70 f[i]=min(f[i],f[j]+g[j][i-1]*p);
71 }
72 }
73 ll ans=linf;
74 for(int i=1;i<=n;i++)
75 if(g[i][n]<linf/2) ans=min(ans,f[i]+g[i][n]*p-Rem[i]);
76 if(ans>=linf/2) puts("-1"); else printf("%lld\n",ans);
77 return 0;
78 }
79
CF1430F Realistic Gameplay (贪心+DP)的更多相关文章
- 【BZOJ-3174】拯救小矮人 贪心 + DP
3174: [Tjoi2013]拯救小矮人 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 686 Solved: 357[Submit][Status ...
- BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP
BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀 ...
- 洛谷P4823 拯救小矮人 [TJOI2013] 贪心+dp
正解:贪心+dp 解题报告: 传送门! 我以前好像碰到过这题的说,,,有可能是做过类似的题qwq? 首先考虑这种显然是dp?就f[i][j]:决策到了地i个人,跑了j个的最大高度,不断更新j的上限就得 ...
- 【bzoj5073】[Lydsy1710月赛]小A的咒语 后缀数组+倍增RMQ+贪心+dp
题目描述 给出 $A$ 串和 $B$ 串,从 $A$ 串中选出至多 $x$ 个互不重合的段,使得它们按照原顺序拼接后能够得到 $B$ 串.求是否可行.多组数据. $T\le 10$ ,$|A|,|B| ...
- 【bzoj3174】[Tjoi2013]拯救小矮人 贪心+dp
题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人,我们知道他从脚 ...
- hdu 1257 最少拦截系统【贪心 || DP——LIS】
链接: http://acm.hdu.edu.cn/showproblem.php?pid=1257 http://acm.hust.edu.cn/vjudge/contest/view.action ...
- 贪心+DP【洛谷P4823】 [TJOI2013]拯救小矮人
P4823 [TJOI2013]拯救小矮人 题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以 ...
- 贪心+dp
贪心+dp 好多题都是这个思想, 可以说是非常重要了 思想一: 在不确定序列无法dp的情况下, 我们不妨先假设序列已经选定, 而利用贪心使序列达到最优解, 从而先进行贪心排序, 在进行dp选出序列 思 ...
- 【题解】CF1056F Write the Contest(三分+贪心+DP)
[题解]CF1056F Write the Contest(三分+贪心+DP) 最优化问题的三个解决方法都套在一个题里了,真牛逼 最优解应该是怎样的,一定存在一种最优解是先完成了耗时长的任务再干别的( ...
随机推荐
- 利用iptables做网络转发
常见的网络拓扑图结构如下: 但是内网服务器偶尔有上网需求,比如yum工具,wget文件.而我们又不能让重要业务直接暴露在公网上. 好用的安全策略有:三层交换机.路由器做nat映射,防火墙做安全策略. ...
- IDEA配置scala
IDEA中配置scala 准备:先下好IDEA和scala安装包,配置好jdk环境 scala不想去官网下载的可以直接去百度网盘下载 链接: 链接:https://pan.baidu.com/s/17 ...
- 攻防世界Web_easytornado
题目: 解题思路: 题目就三个txt文本文件 , 由python_template_injection这篇随笔中了解到tornado也是python web应用程序模板的一种,应该也是考查模板注入. ...
- 在 .NET 平台使用 ReflectionDynamicObject 优化反射调用代码
基于封装的原则,API 的设计者会将部分成员(属性.字段.方法等)隐藏以保证健壮性.但总有需要直接访问这些私有成员的情况. 为了访问一个类型的私有成员,除了更改 API 设计还有就是使用反射技术: p ...
- curl常用参数详解及示例
curl简介 curl是一个开源的命令行工具,它基于网络协议,对指定URL进行网络传输,得到数据后不任何具体处理(如:html的渲染等),直接显示在"标准输出"(stdout)上. ...
- Go1.14版本vendor和gomodule冲突问题
Go1.14版本vendor和gomodule冲突问题 go1.14版本使用go mod tidy构建依赖时会出现问题(见链接), 这个问题在go1.12版本是不会出现的. https://githu ...
- 帆软思迈特软件Smartbi两家区别在哪里?
简单介绍下,从前端展现市场来看,国内这几年帆软算是做的比较好的一家公司,整体市场营销,以及产品易用性也是不错.思迈特公司也是一家专门从事做数据分析平台的公司,也有接近20年的历史,早期从银行.金融证券 ...
- 【计算机基础】IL代码-CLR平台上的字节码【什么是字节码?它与虚拟机的关系?】
字节码(英语:Bytecode)将虚拟机可以读懂的代码称之为字节码.将源码编译成虚拟机读的懂的代码,需要虚拟机转译后才能成为机器代码的中间代码 叫做字节码. 字节码主要为了实现特定软件运行和软件环境. ...
- 【C#程序集】为何.NET Core控制台项目发布后是一个dll文件,而不是exe文件?
因为 .NET Core 的控制台应用默认是生成 dll 文件,而没有对应的 exe 文件.如下图所示,是在VS中编译后生成的结果 图中看到的TestVisualizer.exe 只是一个快捷方式, ...
- 举例说明EF CORE中模型之间的一对多、多对多关系的实现
该例子是我临时想出来的,不具有任何的实际意义.类图如图1所示. 图1 类代码: [Table("student")] public class Student { public i ...