1. 程式人生 > >"多米諾骨牌"問題的動態規劃演算法

"多米諾骨牌"問題的動態規劃演算法

現有n塊”多米諾骨牌”s1,s2,s3,...sn水平放成一排,每次骨牌si包含左右兩個部分,每個部分賦予一個非負整數值,如下圖所示為包含6塊骨牌的序列.骨牌可做180度旋轉,使得原來在左邊的值變到右邊,而原來右邊的值移到左邊,假設不論si如何旋轉,L[i]總是儲存si左邊的值, R[i]總是儲存si右邊的值, W[i]用於儲存si的狀態:當L[i]<=R[i]時記為0,否則記為1,試採用動態規劃演算法設計時間複雜度為o(n)的演算法

 求:R[1]*L[2]+R[2]*L[3]+R[3]*L[4]+R[4]*L[5]+...++R[n-1]*L[n]的最大值,以及當取得最大值時每個骨牌的狀態.
  5|8    4|2     9|6    7|7   3|9    11|10

  s1       s2     s3      s4    s5        s6



#include<iostream>
#include<cstdio>
#include<algorithm>
const int N=100;
using namespace std ;
int main()
{
    int i,j,n,a,b,c,d,ans=0;
    int l[N],r[N],m[2][N]={0},w[N]={0},p[2][N]={0};
    cin>>n;
    for(i=1;i<=n;i++)    cin>>l[i]>>r[i];
    m[0][1]=m[1][1]=0;
    for(i=1;i<n;i++)//
    {
        //  a|b     c|d
        //  si      si+1
        a=l[i],b=r[i];
        c=l[i+1],d=r[i+1];

        if((m[0][i]+b*c)>(m[1][i]+a*c))
            m[0][i+1]+=m[0][i]+b*c,p[0][i+1]=0;
        else  m[0][i+1]+=m[0][i]+a*c,p[0][i+1]=1;

        if((m[0][i]+b*d)>(m[1][i]+a*d))
            m[1][i+1]+=m[0][i]+b*d,p[1][i+1]=0;
        else m[1][i+1]+=m[0][i]+a*d,p[1][i+1]=1;
    }
    if(m[0][n]>m[1][n])  w[n]=0,cout<<m[0][n]<<endl;
    else                 w[n]=1,cout<<m[1][n]<<endl;
    for(i=n;i>1;i--)
        if(w[i]==0) w[i-1]=p[0][i];
        else        w[i-1]=p[1][i];
    for(i=1;i<=n;i++)   cout<<w[i]<<" ";
}

相關推薦

no