P1880 [NOI1995]石子合併

zy嚶嚶嚶
這題,跟能量項鍊比較像哈,反正就是一個加,一個乘,可是,加法確定是要比乘法簡單的,so這題應該也要比能量項鍊簡單(其實兩題真的p區別都沒有) 區間dp,三重循環,第一層區間長度l,第二層區間開始下標i,並求出結束下標j=i+l,第三層k由i到j-1,狀態轉移方程則爲
dp1[i][j]=ma(dp1[i][k]+dp1[k+1][j]+sum[j]-sum[i-1],dp1[i][j])

dp2[i][j]=mi(dp2[i][k]+dp2[k+1][j]+sum[j]-sum[i-1],dp2[i][j])(一大一小)
而因爲這題是個環(能量項鍊也是環),so將本題數據由n個擴展到2n個,最後搜索區間長度爲n的最大及最小值
下面附上代碼ios

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 
 8 int n;
 9 int a[305],sum[305],dp1[305][305],dp2[305][305];
10 
11 int ma(int a,int b){return a>b?a:b;}
12 int mi(int a,int b){return a<b?a:b;}
13 
14 int main(){
15     scanf("%d",&n);
16     for(int i=1;i<=n;i++){
17         scanf("%d",&a[i]);
18         a[i+n]=a[i];
19         sum[i]=sum[i-1]+a[i];
20     }
21     for(int i=1;i<=n;i++){
22         sum[i+n]=sum[i+n-1]+a[i];
23     }
24     for(int l=1;l<n;l++){
25         for(int i=1,j=i+l;i<n+n&&j<n+n;i++,j=i+l){
26             dp2[i][j]=10000000;
27             for(int k=i;k<j;k++){
28                 dp1[i][j]=ma(dp1[i][k]+dp1[k+1][j]+sum[j]-sum[i-1],dp1[i][j]);
29                 dp2[i][j]=mi(dp2[i][k]+dp2[k+1][j]+sum[j]-sum[i-1],dp2[i][j]);
30             }
31         }
32     }
33     int ans1=0,ans2=10000000;
34     for(int i=1;i<=n;i++){
35         ans1=ma(ans1,dp1[i][n+i-1]);
36         ans2=mi(ans2,dp2[i][n+i-1]);
37     }
38     printf("%d\n%d\n",ans2,ans1);
39     return 0;
40 }

嚶嚶嚶新人開博鼓勵一下吧~~spa

相關文章
相關標籤/搜索