朴素做法暴力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)的更多相关文章

  1. 【BZOJ-3174】拯救小矮人 贪心 + DP

    3174: [Tjoi2013]拯救小矮人 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 686  Solved: 357[Submit][Status ...

  2. BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP

    BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀 ...

  3. 洛谷P4823 拯救小矮人 [TJOI2013] 贪心+dp

    正解:贪心+dp 解题报告: 传送门! 我以前好像碰到过这题的说,,,有可能是做过类似的题qwq? 首先考虑这种显然是dp?就f[i][j]:决策到了地i个人,跑了j个的最大高度,不断更新j的上限就得 ...

  4. 【bzoj5073】[Lydsy1710月赛]小A的咒语 后缀数组+倍增RMQ+贪心+dp

    题目描述 给出 $A$ 串和 $B$ 串,从 $A$ 串中选出至多 $x$ 个互不重合的段,使得它们按照原顺序拼接后能够得到 $B$ 串.求是否可行.多组数据. $T\le 10$ ,$|A|,|B| ...

  5. 【bzoj3174】[Tjoi2013]拯救小矮人 贪心+dp

    题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人,我们知道他从脚 ...

  6. hdu 1257 最少拦截系统【贪心 || DP——LIS】

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1257 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  7. 贪心+DP【洛谷P4823】 [TJOI2013]拯救小矮人

    P4823 [TJOI2013]拯救小矮人 题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以 ...

  8. 贪心+dp

    贪心+dp 好多题都是这个思想, 可以说是非常重要了 思想一: 在不确定序列无法dp的情况下, 我们不妨先假设序列已经选定, 而利用贪心使序列达到最优解, 从而先进行贪心排序, 在进行dp选出序列 思 ...

  9. 【题解】CF1056F Write the Contest(三分+贪心+DP)

    [题解]CF1056F Write the Contest(三分+贪心+DP) 最优化问题的三个解决方法都套在一个题里了,真牛逼 最优解应该是怎样的,一定存在一种最优解是先完成了耗时长的任务再干别的( ...

随机推荐

  1. netty系列之:可以自动通知执行结果的Future,有见过吗?

    目录 简介 JDK异步缘起 netty中的Executor Future的困境和netty的实现 总结 简介 在我的心中,JDK有两个经典版本,第一个就是现在大部分公司都在使用的JDK8,这个版本引入 ...

  2. MyBatis功能点一:二级缓存cache

    对于Mybatis缓存分作用域等维度区别一.二级缓存特点如下图: 分析缓存源码首先得找到缓存操作的入口:前面已经分析,sqlsesion.close()仅对一级缓存有影响,而update等对一/二级缓 ...

  3. 封装及其作用Java

    封装 该露的露,该藏的藏 我们程序设计要求"高内聚,低耦合".高内聚就是类的内部数据操作细节自己完成,不允许外部干涉:低耦合:仅暴漏少量的方法给外部使用 ​ 封装(数据的隐藏): ...

  4. Smartbi报表工具的学习笔记,如何学好报表分析?

    近期,因为工作需要,学习了一个报表工具Smartbi,这是国产BI软件,其功能还是挺强大的,并且学习成本很低,容易上手. 其实在学习Smartbi之前,我还学习了一段时间的微软BI工具sqlserve ...

  5. 关于linux下,ls vi等命令失效的解决方法(配置下环境变量出现问题)

    转至:https://www.cnblogs.com/afeiiii/p/13824530.html 配置完环境变量source之后,linux的ls vi命令均失效,报错如下: 解决方法 1.输入  ...

  6. Codeforces Round #769 (Div. 2)D,E

    D.New Year Concert 传送门 题目大意: 一个长为 N ( 1 ≤ N ≤ 2 × 1 0 5 ) N(1\leq N\leq2\times 10^5) N(1≤N≤2×105)的序列 ...

  7. 哈工大 计算机网络 实验二 可靠数据传输协议(停等协议与GBN协议)

    计算机网络实验代码与文件可见github:计算机网络实验整理 实验名称 可靠数据传输协议(停等协议与GBN协议) 实验目的: 本次实验的主要目的. 理解可靠数据传输的基本原理:掌握停等协议的工作原理: ...

  8. COS 音视频实践 | 数据工作流助你播放多清晰度视频

    前言 你是否遇到过这样的场景: 兴致勃勃地观看心爱的视频,正当到了激动人心的高潮部分,却突然因为网速过差被迫陷入"转圈圈"的人生以及社会的大思考中. 又或者是身为网速畅通无阻的vi ...

  9. WPF-ListView单元格设置文字换行

    第2-6行 1 <ListView Name="HumidifyEventLog" Style="{StaticResource ListViewStyle}&qu ...

  10. 矩池云 | Tony老师解读Kaggle Twitter情感分析案例

    今天Tony老师给大家带来的案例是Kaggle上的Twitter的情感分析竞赛.在这个案例中,将使用预训练的模型BERT来完成对整个竞赛的数据分析. 导入需要的库 import numpy as np ...