[kuangbin带你飞]专题二十二 区间DP-E-POJ - 1651
区间DP模板题
做区间DP的题目的时候,我们考虑DP[i][j]的含义是什么?
由题意大概是这样的,我们可以从n个数中每次选一个我们以前没选过的数字拿走,需要消耗a[i]*a[i+1]*a[i-1]的体力。
头和尾不能拿走。问最小消耗的体力是多少?
我们这样考虑。
一般DP[1][n]是答案的话,它代表是拿走了2-n-1,并且两头还有未合并的1,n
那么我们很容易写出转移方程:
DP[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+a[k]*a[k-1]*a[k+1])
#include<iostream> #include<string.h> #include<stdio.h> #include<algorithm> #define LL long long using namespace std; LL dp[106][106]; LL a[106]; const int INF = 0x3f3f3f3f; int main(){ int n; while(~scanf("%d",&n)){ memset(dp,0,sizeof(dp)); for (int i=1;i<=n;i++){ scanf("%lld",&a[i]); } for (int len=3;len<=n;len++){ for (int i=1;i+len-1<=n;i++){ int j=i+len-1; dp[i][j]=INF; for (int k=i+1;k+1<=j;k++){ dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+a[i]*a[j]*a[k]); } } } printf("%lld\n",dp[1][n]); } return 0; }