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) 最优化问题的三个解决方法都套在一个题里了,真牛逼 最优解应该是怎样的,一定存在一种最优解是先完成了耗时长的任务再干别的( ...
随机推荐
- rsync 与 inotify 的使用 & 实现实时同步备份
今日内容 rsync 内容详细 上一篇内容问题 1.yum源问题 2.VPN链接正常,但是没办法通过172 3.VPN链接时,出现了DNS错误 4.掩码不对 5.openvpn开启错误 复制的命令 1 ...
- 用 Beep 函数让主板“唱”《生日歌》
用 Beep 函数,让你的主板也会"唱歌".Beep 可以通过控制主板扬声器的发声频率和节拍来演奏美妙的旋律.本文就通过C#演示,调用Beep函数,演奏生日快乐歌.首先我们来看下 ...
- DDD-领域驱动设计简谈
看到网上讨论 DDD 的文章越来越多,咱也不能甘于人后啊,以下是我对 DDD 的个人理解,短小精悍,不喜忽喷. 也谈DDD(领域驱动设计) 解决什么问题 传统模式,产品评审结束,开发人员就凭经验拆分模 ...
- Python中模块import的使用案例
1 import test # 导入test模块 2 3 print(test.a) # 使用"模块.变量"调用模块中的变量 4 5 test.hi() # 使用"模块. ...
- CobaltStrike逆向学习系列(13):RDI 任务执行流程分析
这是[信安成长计划]的第 13 篇文章 0x00 目录 0x01 任务号 0x02 功能执行 0x03 结果接收 在上一篇文章中已经讲明了 RDI 类型的任务在发布时候的流程,接下来就是执行了,文中不 ...
- [error]ModuleNotFoundError: No module named 'MySQLdb'
错误详情(错误详情如标题,图是网上找的): 解决方法: 在项目目录下 settings.py 的同级目录中的 __init__.py 中加入如下代码: import pymysql pymysql ...
- 转载 CoreCLR源码探索(七) JIT的工作原理(入门篇)
转载自:https://www.cnblogs.com/zkweb/p/7687737.html 很多C#的初学者都会有这么一个疑问, .Net程序代码是如何被机器加载执行的? 最简单的解答是, C# ...
- 【C# 程序集】.net core 3.0中动态卸载|卸载程序集
原文:https://docs.microsoft.com/zh-cn/dotnet/core/dependency-loading/understanding-assemblyloadcontext ...
- 用RecyclerView实现根据位置不同显示不同界面
在原来的基础上将LinearAdapter.java进行修改: 1 public class LinearAdapter extends RecyclerView.Adapter<Recycle ...
- kubernetes配置后端存储 rook-ceph
一 Rook概述 1.1 Ceph简介 Ceph是一种高度可扩展的分布式存储解决方案,提供对象.文件和块存储.在每个存储节点上,将找到Ceph存储对象的文件系统和Ceph OSD(对象存储守护程序)进 ...