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

#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]); }