你最愿意做的哪件事,才是你的天赋所在

0%

动态规划-洛谷P1880

题目链接

落谷P1880

思路

dp[i][j]表示第i~j个石子合并的最小花费得到转移方程

因为i~j需要从i~(j-1)的所有状态推出,所以先枚举i,在枚举j,最后枚举k,保证所有状态都转移到,然后成环就让数列*2就好了

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
* link: https://loj.ac/problem/10147 */
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 500;
int a[N];
ll sum[N];
ll dp[N][N];
ll mdp[N][N];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]),a[i+n]=a[i];
for(int i=1;i<=2*n;i++)sum[i]=sum[i-1]+a[i];
for(int len = 1;len<=n;len++){
for(int i=1;i<=2*n-1;i++){
int j = len+i;
mdp[i][j]=1e9+10;
for(int k=i;k<j&&k<=2*n-1;k++){
dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
mdp[i][j]=min(mdp[i][j],mdp[i][k]+mdp[k+1][j]+sum[j]-sum[i-1]);
}
}
}
ll ansx = 0;
ll ansm = 1e9+10;
for(int i=1;i<=n;i++){
ansx = max(ansx,dp[i][i+n-1]);
ansm = min(ansm,mdp[i][i+n-1]);
}
printf("%lld\n%lld\n",ansm,ansx);
}
-------------你最愿意做的哪件事才是你的天赋所在-------------