• [NOI1995]石子合并


    考试的原题,我居然对了.....因为是一个环,所以你要算一个两遍.....你就要从前往后算一遍,再从后向前算一遍.....

    方程:

    dp1[i][j]=min(dp1[i][k]+dp1[k+1][j]+ans[j]-ans[i-1],dp1[i][j]);
    dp2[i][j]=max(dp2[i][k]+dp2[k+1][j]+ans[j]-ans[i-1],dp2[i][j]);

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(isdigit(ch)==0 && ch!='-')ch=getchar();
        if(ch=='-')f=-1,ch=getchar();
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    inline void write(int x)
    {
        int f=0;char ch[20];
        if(!x){puts("0");return;}
        if(x<0){putchar('-');x=-x;}
        while(x)ch[++f]=x%10+'0',x/=10;
        while(f)putchar(ch[f--]);
        putchar('
    ');
    }
    int dp1[1100][1100];
    int dp2[1100][1100];
    int n,m;
    int a[110000];
    int ans[11000];
    int main()
    {
    	cin>>n;
    	for(int i=1;i<=n;i++)
    	{
    		cin>>a[i];//输入 
    		a[i+n]=a[i];//倒着存一遍 
    	}
    	for(int i=1;i<=2*n;i++)//前缀和 
    	{
    		ans[i]=ans[i-1]+a[i];
    	}
    	for(int i=(n*2)-1;i>=1;i--)//找 
    	{
    		for(int j=i+1;j<=i+n;j++)//赋初值 
    		{
    			dp1[i][j]=2147483647;
    			dp2[i][j]=0;
    			for(int k=i;k<j;k++)
    			{
    				dp1[i][j]=min(dp1[i][k]+dp1[k+1][j]+ans[j]-ans[i-1],dp1[i][j]);
    				dp2[i][j]=max(dp2[i][k]+dp2[k+1][j]+ans[j]-ans[i-1],dp2[i][j]);
    			}
    		}
    	}
    	int sum1=9999999,sum2=0;
    	for(int i=1;i<=n;i++)
    	{
    		sum1=min(sum1,dp1[i][i+n-1]);//依次比较 
    		sum2=max(sum2,dp2[i][i+n-1]);
    	}
    	cout<<sum1<<endl;
    	cout<<sum2<<endl;
    }
    

      

  • 相关阅读:
    Python入门基础知识点(基础数据类型之字典)
    Python入门基础知识点(基础数据类型之二)
    Python入门基础知识点(基础数据类型)
    Python入门基础知识点(循环语句和编码)
    Python入门基础知识点(基础语法介绍)
    接口继承
    类的继承
    类的组合
    静态属性、类方法、静态方法
    类与对象属性的操作
  • 原文地址:https://www.cnblogs.com/dai-jia-ye/p/9378064.html
Copyright © 2020-2023  润新知