Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 9957 | Accepted: 6152 |
Description
Input
Output
Sample Input
6 10 1 50 50 20 5
Sample Output
3650
题目的意思是给定一组数据 不能取最左边和最右边的数 然后每次取一个数的代价是取出的数和它周围两边数的乘积 求只剩最左边和最右边两个数的时候 最小代价是多少
首先分解问题了 一般我们定义的时候 dp[i][j]表示i~j 这个区间的子问题 描述的太模糊了
我们定义 dp[i][j]为i~j区间只剩下i,j两个元素需要的代价 这么定义之后 就可以用到区间dp分割区间的思想了
我们架设存在中间值k 是我们一个区间中最后取走的元素 那么就有dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+a[i]*a[k]*a[j]); 其中k属于i~j
其实就是题意的一个逆向思考
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int inf=10000009; int main() { int t; int dp[101][101],a[101]; while(cin>>t) { for(int i=1;i<=t;i++) cin>>a[i]; //init(); memset(dp,0,sizeof(dp)); for(int l=3;l<=t;l++)// 满足题意的最小区间长度为3 { for(int i=1;i+l-1<=t;i++) { int j=i+l-1; dp[i][j]=inf;// 这个初始化比较重要 for(int k=i+1;k<j;k++) { dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+a[i]*a[k]*a[j]); } } } cout<<dp[1][t]<<endl; } return 0; }
原文:http://www.cnblogs.com/z1141000271/p/6763891.html