Codeforces Round #750 (Div. 2)E. Pchelyonok and Segments (数学+DP)

Link

Gentlemen, self-cultivation and family, governing the country and the world.

Title:

Pchelyonok decides to give Mila a gift. Pchelyonok has "bought" an array a of length n, but he thinks sending an array is too common. He decides to give Mila some of the intervals in this array!

Pchelyonok wants to make his gift prettier, so he decides to select k disjoint intervals from the array such that:

The length of the first interval is k, the length of the second interval is k-1, ..., and the length of the kth interval is 1.

for any i < ji \lt ji<j ,iiThe i interval is in thejjthj interval left. (i.e.ri < lj ) r_i \lt l_j)ri<lj)

The sum of the numbers in these intervals is strictly monotonically increasing. (In symbolic language: let sum ( l , r ) = Σ i = lrai sum(l,r)=\Sigma_{i=l}^{r}a_is u m ( l ,r)=Σi=lrai ,则 s u m ( l 1 , r 1 ) < s u m ( l 2 , r 2 ) < . . . < s u m ( l k , r k ) sum(l_1,r_1) \lt sum(l_2,r_2) \lt...\lt sum(l_k,r_k) s u m ( l1,r1)<s u m ( l2,r2)<...<s u m ( lk,rk)
Pchelenok wants his gift to be as beautiful as possible, so he asks you to find the maximum value of k that satisfies the above conditions.

analyze:

The first must be from the back to the front: why that? Because we definitely moved from short length to long length. How to transfer that? It is nothing more than to find the continuous length of one, the interval and the small. Then we look at the transition equation:
dp [ i ] [ j ] = max ( dp [ i ] [ j ] , sum [ i + j − 1 ] − sum [ i − 1 ] ) dp[i][j]=max (dp[i][j],sum[i+j-1]-sum[i-1])dp[i][j]=max(dp[i][j],sum[i+j1]sum[i1])
d p [ i ] [ j ] dp[i][j] d p ​​[ i ] [ j ] indicates whether the i-th position and length j are legal.

/// 欲戴皇冠,必承其重。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef unsigned long long ull;

#define x first
#define y second
#define PI acos(-1)
#define inf 0x3f3f3f3f
#define lowbit(x) ((-x)&x)
#define debug(x) cout << #x << ": " << x << endl;

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

ll n, m,p;
ll a[N],b[N];
ll dp[N][500];

void solve()
{
    
    
    cin>>n;
    for(int i=1;i<=n;i++){
    
    
        cin>>a[i];
        b[i]=b[i-1]+a[i];
    }
    for(int i=1;i*i<=((n+1)*2);i++) dp[n+1][i]=-1e16;
    dp[n+1][0]=1e16;
    for(int i=n;i>=1;i--){
    
    
        for(int j=0;j*j<=((n+1)*2);j++){
    
    
            dp[i][j]=dp[i+1][j];
            if(j&&i+j-1<=n&&b[j+i-1]-b[i-1]<dp[i+j][j-1]) dp[i][j]=max(dp[i][j],b[i+j-1]-b[i-1]);
        }
    }
    for(int i=sqrt((n+1)*2);;i--){
    
    
        if(dp[1][i]>0) {
    
    
            cout<<i<<endl;
            return ;
        }
    }
}    
int main()
{
    
    
    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=326314415&siteId=291194637