皇室战争

题目大意:

初始有E点体力值,每天可以开宝箱消耗k体力值,体力值要保证>0 每次开宝箱可获得k*a[i]的愉悦度 求最大愉悦度

样例输入1
1
5 2 2
2 1
样例输出1
12
样例1解释
第一天用5体力, 接下来回复2点体力, 用光。
限制与约定
数据编号 cas N E 时间限制(S)
0 10 10 10 1
1 100 100 100 1
2 100 100 1000 1
3 100 10 10^6 1
4 100 10000 10^6 1
5 100 10000 10^6 1
6 20 100000 10^6 3
7 10 500000 10^6 3
8 10 500000 10^6 3
9 10 500000 10^6 3

 

题解:

调整操作的贪心, 直接假设当天直接耗完体力值,然后加入单调栈,每次用i去替换<a[i]的操作.

 

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 using namespace std;
 8 typedef long long ll;
 9 const int N=500005;
10 int gi(){
11     int str=0;char ch=getchar();
12     while(ch>'9' || ch<'0')ch=getchar();
13     while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
14     return str;
15 }
16 int q[N],res[N],a[N];ll ans=0;
17 void work(){
18     int n,m,e;
19     m=gi();e=gi();n=gi();
20     e=min(e,m);
21     for(int i=1;i<=n;i++)a[i]=gi();
22     int r=1;q[1]=1;res[1]=m;ans=(ll)m*a[1];
23     for(int i=2;i<=n;i++){
24         res[i]=e;
25         while(r && a[i]>a[q[r]]){
26             if(res[i]+res[q[r]]>m)ans-=(ll)(m-res[i])*a[q[r]],res[i]=m;
27             else ans-=(ll)a[q[r]]*res[q[r]],res[i]+=res[q[r]];
28             r--;
29         }
30         q[++r]=i;ans+=(ll)res[i]*a[i];
31     }
32     printf("%lld\n",ans);
33 }
34 int main()
35 {
36     freopen("power.in","r",stdin);
37     freopen("power.out","w",stdout);
38     int T=gi();
39     while(T--)
40         work();
41     return 0;
42 }

 

posted @ 2017-07-18 19:33  PIPIBoss  阅读(292)  评论(0编辑  收藏  举报