首页 > 代码库 > 2014多校第四场1005 || HDU 4901 The Romantic Hero (DP)
2014多校第四场1005 || HDU 4901 The Romantic Hero (DP)
题目链接
题意 :给你一个数列,让你从中挑选一些数组成集合S,挑另外一些数组成集合T,要求是S中的每一个数在原序列中的下标要小于T中每一个数在原序列中下标。S中所有数按位异或后的值要与T中所有的数按位与的值相同,问能找出多少符合要求的组合。
思路 :比赛的时候有点没有头绪,后来二师兄想出了状态转移方程,YN又改了很多细节,最后才A的。总之是个别扭的DP。。。。。
一开始是 _xor[i][j^a[i]] += _xor[i-1][j] ;j 的下一个状态 就是异或上a[i],这个数组所代表的意思是,前 i 个数中选取某些数(必须包括 i )组成的集合按位异或得到j^a[i]
但是发现这样会重复,因为对于对于S和T的选取的元素,下标前后没有明显的界限,从前往后找与从后往前找,两厢重复。后来就重新设了一个数组去存以前的所有的值:
_xor[i][j^a[i]] += xort[i-1][j] ;
xort[i][j] = _xor[i][j] + xort[i-1][j] ;//这个表达式,代表这前 i 个中选取了某些数(必须选了 i )异或后的值为j的情况加上前 i -1个选某些值异或后的值为 j 。其实就是选与不选 i 的两种情况相加,组成的就是前 i 个中选取某些数异或出 j 所组成的情况,此时的 i 可选可不选。
1 //4901 2 #include <cstring> 3 #include <cstdio> 4 #include <iostream> 5 typedef long long LL ; 6 const long long mod = 1000000007 ; 7 using namespace std ; 8 9 int a[1050] ;10 LL _xor[1050][1050],xort[1050][1050],_and[1050][1050],andt[1050][1050] ;11 12 void Init()13 {14 memset(_xor,0,sizeof(_xor)) ;15 memset(xort,0,sizeof(xort)) ;16 memset(_and,0,sizeof(_and)) ;17 memset(andt,0,sizeof(andt)) ;18 memset(a,0,sizeof(a)) ;19 }20 int main()21 {22 int T,n ;23 cin >> T ;24 while(T -- )25 {26 cin >> n ;27 Init() ;28 for(int i = 0 ; i < n ; i++)29 cin >> a[i] ;30 _xor[0][a[0]] = xort[0][a[0]] = 1 ;31 for(int i = 1 ; i < n ; i++)32 {33 for(int j = 0 ; j < 1024 ; j ++)34 {35 _xor[i][j^a[i]] += xort[i-1][j] ;36 _xor[i][j^a[i]] %= mod ;37 }38 _xor[i][a[i]] ++ ;39 for(int j = 0 ; j < 1024 ; j++)40 {41 xort[i][j] = _xor[i][j] + xort[i-1][j] ;42 xort[i][j] %= mod ;43 }44 }45 _and[n-1][a[n-1]] = andt[n-1][a[n-1]] = 1 ;46 for(int i = n-2 ; i >= 0 ; i--)47 {48 for(int j = 0 ; j < 1024 ; j++)49 {50 _and[i][j&a[i]] += andt[i+1][j] ;51 _and[i][j&a[i]] %= mod ;52 }53 _and[i][a[i]] ++ ;54 for(int j = 0 ; j < 1024 ; j++){55 andt[i][j] = andt[i+1][j] + _and[i][j] ;56 andt[i][j] %= mod ;57 }58 }59 LL ans = 0 ;60 for(int i = 0 ; i < n-1 ; i++)61 {62 for(int j = 0 ; j < 1024 ; j++)63 {64 ans += (_xor[i][j] * andt[i+1][j]) % mod ;65 ans %= mod ;66 }67 }68 cout << ans << endl ;69 }70 return 0 ;71 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。