zoukankan      html  css  js  c++  java
  • 环形的处理P1880 [NOI1995]石子合并

    Description

    在一个圆形操场的四周摆放 N 堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
    试设计出一个算法,计算出将 N 堆石子合并成 1堆的最小得分和最大得分。

    数据的第 1 行是正整数 N,表示有N堆石子。
    第 2 行有 N个整数,第 i 个整数 (a_i)表示第 i 堆石子的个数。
    输出共 2 行,第 1 行为最小得分,第 2行为最大得分。

    Input

    4
    4 5 9 4

    Output

    43
    54

    Analysis

    决策容易分析,最优子结构有两部分
    断环为链:将长度为n的链复制一份接在后面,环的情况就是长度为2n的链中任意连续的长度为n的链。

    Code

    我的写法

    #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
    %d",mini,maxi);
        return 0;
    }
    

    另一种写法

    #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;
    }
    
  • 相关阅读:
    HDU 1800 Flying to the Mars 字典树,STL中的map ,哈希树
    字典树 HDU 1075 What Are You Talking About
    字典树 HDU 1251 统计难题
    最小生成树prim算法 POJ2031
    POJ 1287 Networking 最小生成树
    次小生成树 POJ 2728
    最短路N题Tram SPFA
    poj2236 并查集
    POJ 1611并查集
    Number Sequence
  • 原文地址:https://www.cnblogs.com/chanceYu/p/12163451.html
Copyright © 2011-2022 走看看