P1880 [NOI1995] Stone merger

Topic description

Place N piles of stones around a circular playground, and now combine the stones into a pile in an orderly manner. It is stipulated that only 2 adjacent piles can be selected to merge into a new pile at a time, and the new pile of stones can be merged into a new pile. number, recorded as the combined score.

Try to design an algorithm to calculate the minimum and maximum scores for combining N piles of stones into one pile.

Input and output format

Input format:

The first row of the data is a positive integer N, 1≤N≤100, which means there are N piles of stones. The second row has N numbers, which respectively represent the number of stones in each pile.

Output format:

The output has a total of 2 lines, the first line has the minimum score, and the second line has the maximum score.

Input and output example

Input Example #1: Copy
4
4 5 9 4
Output Sample #1: Copy
43
54

 

Solution:

  This question can not be greedy, you can find it casually.

  Considering the interval $DP$, let $f[i][j]$ represent the cost of combining $ij$, and $sum[i]$ represent the prefix sum of costs to $i$. Since it is a ring, it is directly broken into a chain in the original Copy the original array after the array, and it is not difficult to get the state transition equation: $f[i][j]=max(f[i][j],f[i][k]+f[k+1][j ]+s[j]-s[i-1]),k\in[i,j)$, pay attention to the boundary $f[i][i]=0,f[i][i+1]=s[ i+1]-s[i-1]$, recursive enumeration interval length, because it is a ring, so the target state is the minimum\maximum value in $f[i][n+i-1]$.

Code:

 

 1 #include<bits/stdc++.h>
 2 #define il inline
 3 #define ll long long
 4 #define Min(a,b) (a)>(b)?(b):(a)
 5 #define Max(a,b) (a)>(b)?(a):(b)
 6 #define f_for(a,b,i) for(int (i)=(a);(i)<=(b);(i)++)
 7 using namespace std;
 8 const int N=205;
 9 int n,a[N],s[N],f1[N][N],f2[N][N],ans1=520520520,ans2;
10 int main(){
11     ios::sync_with_stdio(0);
12     cin>>n;
13     memset(f1,0x3f,sizeof(f1));memset(f2,-0x3f,sizeof(f2));
14     f_for(1,n,i)cin>>a[i],a[i+n]=a[i],f1[i][i]=f2[i][i]=f1[i+n][i+n]=f2[i+n][i+n]=0;
15     f_for(1,(n<<1)-1,i)s[i]=a[i]+s[i-1];
16     f_for(1,n-1,l) 
17     f_for(1,(n<<1)-1,i){ 
18         int j=i+l;
19         if(j>((n<<1)))break;
20         if(l==1)f1[i][j]=f2[i][j]=s[j]-s[i-1];
21         else f_for(i,j-1,k)
22             f1[i][j]=Min(f1[i][j],f1[i][k]+f1[k+1][j]+s[j]-s[i-1]),
23             f2[i][j]=Max(f2[i][j],f2[i][k]+f2[k+1][j]+s[j]-s[i-1]);
24     }
25     f_for(1,n,i)
26         if((i+n-1)>((n<<1)))break;
27         else ans1=Min(ans1,f1[i][i+n-1]),ans2=Max(ans2,f2[i][i+n-1]);
28     cout<<ans1<<endl<<ans2;
29     return 0;
30 
31 }

 

Guess you like

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