当前位置: 代码迷 >> 综合 >> 多米诺骨牌
  详细解决方案

多米诺骨牌

热度:41   发布时间:2024-01-24 09:29:33.0

现有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




  
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. const int N= 100;
  5. using namespace std ;
  6. int main()
  7. {
  8. int i,j,n,a,b,c,d,ans= 0;
  9. int l[N],r[N],m[ 2][N]={ 0},w[N]={ 0},p[ 2][N]={ 0};
  10. cin>>n;
  11. for(i= 1;i<=n;i++) cin>>l[i]>>r[i];
  12. m[ 0][ 1]=m[ 1][ 1]= 0;
  13. for(i= 1;i<n;i++) //
  14. {
  15. // a|b c|d
  16. // si si+1
  17. a=l[i],b=r[i];
  18. c=l[i+ 1],d=r[i+ 1];
  19. if((m[ 0][i]+b*c)>(m[ 1][i]+a*c))
  20. m[ 0][i+ 1]+=m[ 0][i]+b*c,p[ 0][i+ 1]= 0;
  21. else m[ 0][i+ 1]+=m[ 0][i]+a*c,p[ 0][i+ 1]= 1;
  22. if((m[ 0][i]+b*d)>(m[ 1][i]+a*d))
  23. m[ 1][i+ 1]+=m[ 0][i]+b*d,p[ 1][i+ 1]= 0;
  24. else m[ 1][i+ 1]+=m[ 0][i]+a*d,p[ 1][i+ 1]= 1;
  25. }
  26. if(m[ 0][n]>m[ 1][n]) w[n]= 0, cout<<m[ 0][n]<< endl;
  27. else w[n]= 1, cout<<m[ 1][n]<< endl;
  28. for(i=n;i> 1;i--)
  29. if(w[i]== 0) w[i -1]=p[ 0][i];
  30. else w[i -1]=p[ 1][i];
  31. for(i= 1;i<=n;i++) cout<<w[i]<< " ";
  32. }