皇室战争
题目大意:
初始有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 }