HDU 4901 The Romantic Hero

举报
Linux猿 发表于 2021/08/04 23:45:46 2021/08/04
【摘要】 题目链接~~> 做题感悟:这题 dp 思路倒是好想,但是写的时候就手残了,结果一直wa !! 解题思路:                  因为相与的全在右边,抑或的全在左边,因此需要正向 dp 抑或一下,需要开三维的dpA [  i  ] [ &nbsp...

题目链接~~>

做题感悟:这题 dp 思路倒是好想,但是写的时候就手残了,结果一直wa !!

解题思路:

                 因为相与的全在右边,抑或的全在左边,因此需要正向 dp 抑或一下,需要开三维的dpA [  i  ] [  S  ] [  k  ]  ( k = 0 , 1)  k = 0 ,代表前 i 个数达到状态 S 且没有选入第 i 个值所得到的最多的次数,k = 1 代表选入第 i 个数达到状态 S 所得到的最多次数  ,同样,需要逆向 dp 相与一下,dpB [  i  ] [  S  ] [  k  ]  ( k = 0 ,  1 ) , k = 0  ,代表逆向到达 i ,达到状态 S 且没选入第 i 个值所得到的最多次数 , k = 1  , 代表逆向到达 i ,达到状态 S 且选入第 i 个值所得到的最多次数。

               最后,ans = ans + dpA[ i ] [ S ][ 1 ] * dpB[ i ] [ S ] [ 0 ]  ;  dpA 代表正向抑或包含 i 到达状态 S 的最多次数,dpB 代表逆向相与达到状态S 的最多次数。 

代码:


  
  1. #include<iostream>
  2. #include<fstream>
  3. #include<iomanip>
  4. #include<ctime>
  5. #include<fstream>
  6. #include<sstream>
  7. #include<stack>
  8. #include<cstring>
  9. #include<cmath>
  10. #include<map>
  11. #include<vector>
  12. #include<cstdio>
  13. #include<algorithm>
  14. #define INT __int64
  15. using namespace std ;
  16. const double esp = 0.00000001 ;
  17. const INT mod = 1e9 + 7 ;
  18. const INT MY = 1000 + 10 ;
  19. const INT MX = 2048 + 10 ;
  20. INT n ;
  21. INT g[MY] ;
  22. INT dpA[MY][MX][2] ,dpB[MY][MX][2] ;
  23. void DP()
  24. {
  25. for(INT i = 1 ;i <= n ; ++i) // 正向抑或 dp
  26. for(INT S = 0 ;S <= 1024 ; ++S)
  27. {
  28. dpA[i][S^g[i]][1] += (dpA[i-1][S][0] + dpA[i-1][S][1]) % mod ;
  29. dpA[i][S][0] = (dpA[i-1][S][0] + dpA[i-1][S][1]) % mod ;
  30. }
  31. for(INT i = n ;i >= 1 ; --i) // 逆向与 dp
  32. for(INT S = 0 ;S <= 1024 ; ++S)
  33. {
  34. dpB[i][S&g[i]][1] += (dpB[i+1][S][0] + dpB[i+1][S][1]) % mod ;
  35. dpB[i][S][0] = (dpB[i+1][S][0] + dpB[i+1][S][1]) % mod ;
  36. }
  37. INT ans = 0 ;
  38. for(INT i = 1 ;i <= n ;i++) // 计算总的次数
  39. for(INT S = 0 ;S <= 1024 ; ++S)
  40. ans = (ans + (dpA[i][S][1]*dpB[i][S][0]) % mod) % mod ;
  41. cout<<ans%mod<<endl ;
  42. }
  43. int main()
  44. {
  45. INT Tx ;
  46. scanf("%I64d" ,&Tx) ;
  47. while(Tx--)
  48. {
  49. scanf("%I64d" ,&n) ;
  50. memset(dpA ,0 ,sizeof(dpA)) ;
  51. memset(dpB ,0 ,sizeof(dpB)) ;
  52. for(INT i = 1 ;i <= n ;i++)
  53. {
  54. scanf("%I64d" ,&g[i]) ;
  55. dpA[i][g[i]][1] = dpB[i][g[i]][1] = 1 ; // 只有一个数的时候
  56. }
  57. DP() ;
  58. }
  59. return 0 ;
  60. }


文章来源: blog.csdn.net,作者:Linux猿,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/nyist_zxp/article/details/38612497

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。