ARC 128 C - Max Dot (DP+ Thinking)

Link

Title:

Given you n, m, s, and n numbers a[i], let you construct a sequence p of length n such that ∑ pi ∗ ai \sum p_i*a_ipiaimaximum, and the following conditions must be met

  • 0 < = p 1 < = p 2 < = . . . . < = p n < = m 0<=p_1<=p_2<=....<=p_n<=m0<=p1<=p2<=....<=pn<=m
  • ( ∑ p i ) = s (\sum p_i)=s(pi)=s

analyze:

First of all, we use three-segment division. As for why we need three-segment division, because it requires monotonically increasing, then the latter must be large. In order to maximize the answer, we must make the latter segment the same, and divide the remaining front segment equally in the middle. is 0.
Now that we know that we need a syllogism, we can just enumerate the left and right endpoints of the middle paragraph. The
third paragraph is the maximum value M, the second paragraph is the average of the remaining, the first paragraph is 0, and then find maximum answer.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define x first
#define y second
#define sf scanf
#define pf printf
#define PI acos(-1)
#define inf 0x3f3f3f3f
#define lowbit(x) ((-x)&x)
#define mem(a,x) memset(a,x,sizeof(a))
#define rep(i,n) for(int i=0;i<(n);++i)
#define repi(i,a,b) for(int i=int(a);i<=(b);++i)
#define repr(i,b,a) for(int i=int(b);i>=(a);--i)
#define debug(x) cout << #x << ": " << x << endl;

const int MOD = 998244353;
const int mod = 1e9 + 7;
const int MAX = 2e5 + 10;
const int dx[] = {
    
    0, 1, -1, 0, 0};
const int dy[] = {
    
    0, 0, 0, 1, -1};
const int dz[] = {
    
    1, -1, 0, 0, 0, 0 };
int day[] = {
    
    0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};


void init()
{
    
    

}
ll qpow(ll a, ll b, ll p)
{
    
    
    ll ans = 1;
    while(b)
    {
    
    
        if(b & 1) ans = ans * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return ans;
}


string str;
ll n,m,s;
ll a[MAX];
double sum[MAX];
void solve()
{
    
    
    cin>>n>>m>>s;
    for(int i = 1 ;i <=n;i++){
    
    
        cin>>a[i];        
        sum[i]=sum[i-1]+double(a[i]);
    }
    double res=0.0;
    for(int i=0;i<=n;i++){
    
    ///左端点
        for(int j=i+1;j<=n+1;j++){
    
    
            double num=s-m*(n-j+1);///最后一段 用了多少 
            if(num<0.0||num>(j-i-1)*m) continue; //不够, 
            double ans=m*(sum[n]-sum[j-1]);///后半段得到价值
            if(j>i+1) {
    
    ///中间有平分的那一段
                ans += (sum[j-1]-sum[i])*num/(double)(j-i-1);
            }
            res=max(res,ans);
        }
    }
    printf("%.10lf\n",res);
}

int main()
{
    
    
    init();
    ll t = 1;
    ///scanf("%lld", &t);
    while(t--)
    {
    
    
        solve();
    }
    return 0;
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326314428&siteId=291194637
arc