首页 > 代码库 > POJ 1651 Multiplication Puzzle (区间dp)

POJ 1651 Multiplication Puzzle (区间dp)

题目大意:对n个数组成的序列取数,规定最两边不能取,每次取一个a[i],得到 a[l] * a[i] * a[r] 的分数(a[l]是a[i]左边的数,a[r]是a[i]右边的数),并把这个数从序列中移走,求n-2次取数后的得分和的最小值

分析:正着确定状态不好做,不如反着来,设dp[l][r]为向区间[l, r]中填满数所得到分数和的最小值,考虑最近一次填数的位置,不难得出:

dp[l][r] = fmin(dp[l][m] + dp[m][r] + a[l] * a[m] * a[r]) (l<m<r);

实现方式可以选择记忆化递归,也可直接以区间长度为阶段来递推,各有优缺点,代码如下:

  1 /**********************************************  2 ***    Problem:  3 ***    Author:        JKL  4 ***    University:    CSUST  5 ***    Team:          __Dream  6 ***    Email:          1451108308@QQ.COM  7 ***    My Blog:        http://www.cnblogs.com/jklongint/  8 ***********************************************/  9 //=================================================== 10 #include <iostream> 11 #include <fstream> 12 #include <sstream> 13 #include <iomanip> 14 #include <cstdio> 15 #include <cstdlib> 16 #include <cmath> 17 #include <cassert> 18 #include <numeric> 19 #include <ctime> 20 #include <algorithm> 21 #include <cstring> 22 #include <string> 23 #include <vector> 24 #include <queue> 25 #include <map> 26 #include <stack> 27 #include <list> 28 #include <set> 29 #include <bitset> 30 #include <deque> 31 using namespace std; 32 //--------------------------------------------------- 33 #define mem(a,b) memset(a,b,sizeof(a)) 34 #define GO cout<<"HelloWorld!"<<endl 35 #define Case(x) cout<<"Case "<<x<<":" 36 #define foru(i,n) for(int i=1; i <= n; i++) 37 #define ford(i,n) for(int i = n; i >= 1; i--) 38  #define fin freopen("input.txt","r",stdin); 39  #define fout freopen("output.txt","w",stdout) 40 #define lson  l, m, rt << 1 41 #define rson  m + 1, r, rt << 1 | 1 42  43 #define sqr(a)  ((a)*(a)) 44 #define abs(a) ((a>0)?(a):-(a)) 45 #define pii pair<int,int> 46  47 #define fmax(a,b) max(a,b) 48 #define fmin(a,b) min(a,b) 49 #define fmax3(a,b,c)  (fmax(a,fmax(a,b))) 50 #define fmin3(a,b,c)  (fmin(a,fmin(a,b))) 51  52 #define sfi(x) scanf("%d",&x) 53 #define sfL(x) scanf("%I64d",&x) 54 #define sfc(x) scanf("%c",&x) 55 #define sfd(x) scanf("%lf",&x) 56 #define sfs(x) scanf("%s",x) 57 #define sfii(a,b) scanf("%d%d",&a,&b) 58 #define sfLL(a,b) scanf("%I64d%I64d",&a,&b) 59 #define sfcc(a,b) scanf("%c%c",&a,&b) 60 #define sfdd(a,b) scanf("%lf%lf",&a,&b) 61 #define sfss(a,b) scanf("%s%s",a,b) 62  63 #define pfi(x) printf("%d",x) 64 #define pfL(x) printf("%I64d",x) 65 #define pfs(x) printf("%s",x) 66 #define pfd(x) printf("%lf",x) 67 #define pfc(x) print("%c",x) 68 #define newLine pfs("\n") 69 #define space pfs(" ") 70  71 //-------------------------------------------------------- 72 typedef long long LL; 73 typedef unsigned long long ULL; 74 typedef __int64 __LL; 75 typedef unsigned __int64 __ULL; 76  77 typedef vector<int> vi; 78 typedef vector<LL> vL; 79 typedef vector<string> vs; 80 typedef set<int> si; 81 typedef map<int,int> mii; 82 typedef map<LL,LL> mLL; 83 typedef map<string,int> msi; 84 typedef map<char,int> mci; 85 //-------------------------------------------------------- 86 const int dx[4]={1,-1,0,0}; 87 const int dy[4]={0,0,1,-1}; 88  const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 89  const int N6=1000006; 90  const int N5=100006; 91  const int N4=10006; 92  const int N3=1006; 93  const int N2=106; 94  const int N=1009; 95  const int MOD=1000000007; 96  const LL LMAX=0x7fffffffffffffff; 97  const LL IMAX=0x3fffffff; 98  const double PI=3.14159265359; 99 //--------------------------------------------------------100 template< class T > T gcd(T a, T b) { return (b != 0 ? gcd<T>(b, a%b) : a); }101 template< class T > T lcm(T a, T b) { return (a / gcd<T>(a, b) * b); }102 103 //------------------------------------------------------------104 struct TreeNode{105     LL  sum, add;106 };107 //=================================================================108 TreeNode tree[N << 3];109 int flag[N][N], a[N], dp[N][N];110 int dpSearch(int l, int r)111 {112     if(l + 1 == r)return 0;113     if(flag[l][r])return dp[l][r];114     dp[l][r] = IMAX;115     for(int j = l + 1; j < r; j++){116         int s = dpSearch(l, j), t = dpSearch(j, r);117         //if(l == 1 && r == 4)cout<< s<< t<< endl;118         dp[l][r] = fmin(dp[l][r], s + t + a[l] * a[j] * a[r]);119     }120     flag[l][r] = 1;121     //cout<<l<<r<<dp[l][r]<<endl;122     return dp[l][r];123 }124 int main()125 {126     //fin;//fout;//freopen("input.txt","r",stdin);127     int n;128     cin>>n;129     foru(i, n)sfi(a[i]);130     cout << dpSearch(1, n) << endl;131     return 0;132 }
View Code