首页 技术 正文
技术 2022年11月21日
0 收藏 531 点赞 3,641 浏览 2854 个字

朴素做法暴力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
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,000
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,512
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,358
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,141
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,771
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,849