标签:图片 ace div 就是 play you mes none 之间
动态规划要从最优子结构来推出大的方案
对于本题,我们要思考,什么是大的,什么是小的。
或许有些人会想设计状态为f[i],表示我从1-i的最小花费,但是仅仅这样是不够的,因为在这之间进小黑屋的不一定要在这之间就出来,他有后效性
那么什么是没有后效性的呢,如果我们判定这个区间就是全部的大小,他没有后面还在排队了,那么这就不会产生后效影响了
所以我们对这个方程进行改换定义,定义他为f[i][j],也就是我从i-j的最小花费且不算他前面的数,也就是我每个区间都是从第一个开始的,这样就不会被别的影响了,
那我们想我们如何转移方程呢?
在我们的对状态定义之后,不难发现要用区间dp
那么f[l][r]=min(a[i]*(k-1)+f[i+1][i+k-1]+f[i+k][j]+k*(sum[j]-sum[i+k-1]))
他的意思是我第l个数我第几个走,我们发现.f[i+1][i+k-1],f[i+k][j]这两个区间都是计算过的,且题目告诉我们先进的最后出来,这样就完美的符合转移的关系
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int inf=0x3f3f3f3f; int dp[102][102]; int a[105]; int sum[105]; int main(){ int t; cin>>t; int cas=0; while(t--){ cas++; int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i]; int len=1; int i,j,k; for(i=1;i<n;i++){ for(j=i+1;j<=n;j++) dp[i][j]=inf; } for(len=1;len<=n;len++){ for(i=1;i+len-1<=n;i++){ j=len+i-1; for(k=1;k<=len;k++){ dp[i][j]=min(dp[i][j],a[i]*(k-1)+dp[i+1][i+k-1]+dp[i+k][j]+k*(sum[j]-sum[i+k-1])); } } } printf("Case #%d: %d\n",cas,dp[1][n]); } return 0; }
HDU4283 You Are the One(经典区间dp)
标签:图片 ace div 就是 play you mes none 之间
原文地址:https://www.cnblogs.com/ctyakwf/p/12327494.html