E - Maximize Rating (atcoder.jp)
vp的时候想到了具体细节实现没写出来,码力有待加强
分析:提取题意,我们需要选择一些比赛,然后根据已经选择的比赛的场次先后顺序(这是重点),通过公式计算出最大值
一眼暴力,然而一看数据范围,n=5000,所以Q也有5000,显然枚举所有方案这个想法不可行
优化
我们注意到如果不考虑顺序,我们可以通过01背包求解,dp[j] = max ( dp[j] , dp[j-1] + arr[i] * p ),其中p是0.9的 j-1 次方的缩写,然后考虑最后的1200 / sqrt(k)
我们可以将当前 arr[i]能影响到的 dp[j] (1<=j<=n) 范围变成 dp[j] (1<=j<=i) ,当然,也是要像01背包那样倒着循环,然后转移方程也需要改变 dp[j] = max ( dp[j] , dp[j-1]*0.9 + arr[i] ),因为固定了顺序,最新加入的数永远是*1滴,然后之前的值都要*0.9,vp时就是这个出了问题,没想明白。
#include <iostream>
#include <cstring>
#include <algorithm>
#include<cmath>
using namespace std;
const int N=1000010;
double a[N],f[N],b[N];
double dp[5010];
signed main(){
int n,m;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
for(int j=i;j>=1;j--){
dp[j]=max(dp[j],dp[j-1]*0.9+a[i]);
}
}
double ans= -1e18;
double now=1,sum=0;
for(int i=1;i<=n;i++){
sum+=now;
double tmp=dp[i]/sum-1200.0/sqrt(i);
ans=max(ans,tmp);
now*=0.9;
}
printf("%.15f",ans);
}