Processing annular P1880 [NOI1995] combined gravel

Description

Playground around a circular stones piled placed N, Stone is to have order to merge into a pile. Each time only a predetermined selected adjacent stack 2 into a new pile and the new pile of stones number, remember that the combined score.
Test design an algorithm to calculate the N stones piled into a stack the minimum combined score and maximum score.

The first row of data is a positive integer N, the N stones piled there.
The second row of N integers, the first integer i \ (a_i \) represents the number of i-th stack stones.
The output common line 2, line 1 is the minimum score, the maximum score of the second row.

Input

4
4 5 9 4

Output

43
54

Analysis

Decision easy to analyze, optimal substructure has two parts
broken ring chain: the chain length n is a replication connected behind a ring of the chain length is 2n in any continuous chain of length n.

Code

I wording

#include<bits/stdc++.h>
using namespace std;
int s[101],a[100],xp[100][100],dp[100][100];
int main(){
    int n,i,j,maxi=0,mini=200000;scanf("%d",&n);
    for(i=0;i<n;++i){
        scanf("%d",&a[i]);
        s[i+1]=s[i]+a[i];s[i+1+n]=s[i+1];
    }
    for(i=0;i<n;++i)s[i+1+n]+=s[n];
    for(int z=1;z<n;++z)for(i=0;i<n;++i){        
        j=i+z;xp[i][j%n]=200000;
        for(int k=i;k<j;++k){
            xp[i][j%n]=min(xp[i][j%n],xp[i][k%n]+xp[(k+1)%n][j%n]+s[j+1]-s[i]);
            dp[i][j%n]=max(dp[i][j%n],dp[i][k%n]+dp[(k+1)%n][j%n]+s[j+1]-s[i]);
            if(z==n-1)mini=min(mini,xp[i][j%n]);
            if(z==n-1)maxi=max(maxi,dp[i][j%n]);
        }
    }
    printf("%d\n%d",mini,maxi);
    return 0;
}

Another way

#include<bits/stdc++.h>
using namespace std;
int n,l,anss,ansb,a[110],sum[210],dp[210][210],dpbig[210][210];
int main(){
    memset(dp,0x3f,sizeof(dp)); anss=dp[0][0];
    cin>>n;
    for (int i=1;i<=n;i++) cin>>a[i]; a[0]=a[n];
    for (int i=1;i<=2*n;i++){
        sum[i]=sum[i-1]+a[i%n];
        dp[i][i]=0;
    }
    for (int len=2;len<=n;len++){
        for (int r=len;r<=2*n;r++){
            l=r-len+1;
            for (int j=l;j<r;j++){
                dp[l][r]=min(dp[l][j]+dp[j+1][r]+sum[r]-sum[l-1],dp[l][r]);
                dpbig[l][r]=max(dpbig[l][j]+dpbig[j+1][r]+sum[r]-sum[l-1],dpbig[l][r]);
            }
        }
    }
    for (int i=1;i<=n;i++){
        anss=min(dp[i][i+n-1],anss);
        ansb=max(dpbig[i][i+n-1],ansb);
    }
    cout<<anss<<endl;
    cout<<ansb;
    return 0;
}

Guess you like

Origin www.cnblogs.com/chanceYu/p/12163451.html