合并石子 区间dp水题
生活随笔
收集整理的這篇文章主要介紹了
合并石子 区间dp水题
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
合并石子?
鏈接: nyoj 737
描述: 有N堆石子排成一排,每堆石子有一定的數(shù)量。現(xiàn)要將N堆石子并成為一堆。合并的過程只能每次將相鄰的兩堆石子堆成一堆,每次合并花費的代價為這兩堆石子的和,經(jīng)過N-1次合并后成為一堆。求出總的代價最小值。tags:最基本的區(qū)間dp,這題范圍小,如果n大一些,還是要加個平行四邊行優(yōu)化。 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<string> using namespace std; typedef long long ll; #define rep(i,a,b) for(int i=a; i<=b; ++i) #define inf 1e18 const int N=1005;int n, a[N]; ll dp[N][N], f[N][N], sum[N][N], sum1[N]; int main() {while(scanf("%d", &n)!=EOF) {rep(i,1,N-1) rep(j,i,N-1) dp[i][j]=inf;rep(i,1,n) scanf("%d", &a[i]), sum1[i]=sum1[i-1]+a[i];rep(i,1,n) rep(j,i+1,n) {sum[i][j]=sum1[j]-sum1[i-1];}rep(i,1,n) f[i][i]=i, dp[i][i]=0;rep(len, 2, n) for(int i=1; i+len-1<=n; ++i){int j=i+len-1;for(int k=f[i][j-1]; k<=f[i+1][j]; ++k){ if(dp[i][j]>dp[i][k]+dp[k+1][j]+sum[i][j]) {dp[i][j]= dp[i][k]+dp[k+1][j]+sum[i][j];f[i][j]=k;}} }printf("%lld\n", dp[1][n]);}return 0; }轉載于:https://www.cnblogs.com/sbfhy/p/6903667.html
總結
以上是生活随笔為你收集整理的合并石子 区间dp水题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 组合部分标签向量并累加成完整向量
- 下一篇: 添加gitlab远程账号 使用注意事项