dp--区间dp P1880 [NOI1995]石子合并
作者:互联网
题目描述
在一个圆形操场的四周摆放 N 堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出一个算法,计算出将 N 堆石子合并成 1 堆的最小得分和最大得分。
输入格式
数据的第 1 行是正整数 N,表示有N堆石子。
第 2 行有 N 个整数,第 i 个整数 ai 表示第 i 堆石子的个数。
输出格式
输出共 2 行,第 1 行为最小得分,第 2 行为最大得分。
规定一个划分线,i到j个石子所能得到的最大得分和最小得分,是i到k得到的最大分数或最小得分,加上k+1到j的最大分数或最小得分,再加上,合并后的到的分数的最大值和最小值。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 using namespace std; 5 const int inf=0x3f3f3f; 6 int n,minl,maxl,f1[300][300],f2[300][300],num[300]; 7 int s[300]; 8 inline int d(int i,int j){return s[j]-s[i-1];} 9 int main() 10 { 11 scanf("%d",&n); 12 for(int i=1;i<=n;i++) 13 { 14 scanf("%d",&num[i]); 15 num[i+n]=num[i]; 16 } 17 for(int i=1;i<=2*n;i++) 18 { 19 s[i]=s[i-1]+num[i]; 20 } 21 for(int p=1;p<n;p++) 22 { 23 for(int i=1,j=i+p;(j<n+n) && (i<n+n);i++,j=i+p) 24 { 25 f2[i][j]=inf; 26 for(int k=i;k<j;k++) 27 { 28 f1[i][j] = max(f1[i][j], f1[i][k]+f1[k+1][j]+d(i,j)); 29 f2[i][j] = min(f2[i][j], f2[i][k]+f2[k+1][j]+d(i,j)); 30 } 31 } 32 } 33 minl=inf; 34 for(int i=1;i<=n;i++) 35 { 36 maxl=max(maxl,f1[i][i+n-1]); 37 minl=min(minl,f2[i][i+n-1]); 38 } 39 printf("%d\n%d",minl,maxl); 40 return 0; 41 }
标签:得分,int,NOI1995,石子,合并,P1880,300,include,dp 来源: https://www.cnblogs.com/very-beginning/p/12219397.html