Doin' Time Gym - 103107D (区间DP,逆元)

D. Doin' Time
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
One day, Fop_zz is playing a boring game merge numbers though he is busy.

There is a sequence {ai} of length N and he should play this game for n−1 turns. In one turn, he chooses an index x and then he merges ax and ax+1 to ax×ax+1mod1000003 and gets (ax−ax+1)2 scores.

So, after one turn, the length of sequence will decrease exactly one, and after the last turn there's only 1 integer in the sequence and he stops.

Now he want to know the maximum total scores he can get. Can you help him?

Input
The first line contains one integer N (1≤N≤300) denoting the length of sequence.

The second line contains N integers a1,a2,⋯,an (1≤ai≤106).

Output
Output one line with only one integer denoting the answer.

Example
inputCopy
3
1 2 3
outputCopy
26
View Problem
#include <bits/stdc++.h>
using namespace std;
#define ri register int
#define M 305
#define mod 1000003

template <class G> void read(G &x)
{
    x=0;int f=0;char ch=getchar();
    while(ch<'0'||ch>'9'){f|=ch=='-';ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    x=f?-x:x;
    return ;
}

int n,m;
long long val[M];
long long arr[M];
long long dp[M][M];
long long inv[M];
long long get(long long a,int b)
{
    long long ans=1;
    while(b)
    {
        if(b&1) ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
long long ck(int i,int k,int j)
{
    //cout<<abs(arr[k]/arr[i-1]-arr[j]/arr[k])*abs(arr[k]/arr[i-1]-arr[j]/arr[k])<<endl;
    return abs(arr[k]*inv[i-1]%mod-arr[j]*inv[k]%mod)*abs(arr[k]*inv[i-1]%mod-arr[j]*inv[k]%mod);
}
int main(){
    
    read(n);arr[0]=1;inv[0]=1;
    for(ri i=1;i<=n;i++)
    {
        read(val[i]);
        arr[i]=arr[i-1]*val[i]%mod;
        inv[i]=get(arr[i],mod-2);
    }
    for(ri i=1;i<=n;i++) dp[i][i]=0;
    for(ri t=1;t<n;t++)
    {
        for(ri i=1;i+t<=n;i++)
        {
            int j=i+t;
            for(ri k=i;k<j;k++)
            {
                dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+ck(i,k,j));
            }
        }
    }
    printf("%lld",dp[1][n]);
    
    
    

} 
View Code

 

posted @ 2022-03-22 20:56  VxiaohuanV  阅读(38)  评论(0编辑  收藏  举报