HDU4901 The Romantic Hero DP

 题意:给你n个数,问你将数分成两个数组,S,T ,T 中所有元素的需要都比S任意一个大,问你S中所有元素进行 XOR 操作和 T 中所有元素进行 &操作值相等的情况有多少种。

解题思路:两个二维DP,等于背包问题,dpy[i][j] 代表选 数组 S 前 i 个数 状态为 j 的 情况有多少种。(这个是从前往后dp的)

然后我们还需要知道 dpx[i][j] ,代表选 T 数组 i-n个数的时候状态为 j 的情况数, (从后往前dp)

答案就是中间过程中  dpx[i]][j], i 必选的那种情况,把这种情况和前面  dpy 对应情况相乘累加就行。

解题代码:

 1 // File Name: 1005.cpp
 2 // Author: darkdream
 3 // Created Time: 2014年07月31日 星期四 15时38分31秒
 4 
 5 #include<vector>
 6 #include<list>
 7 #include<map>
 8 #include<set>
 9 #include<deque>
10 #include<stack>
11 #include<bitset>
12 #include<algorithm>
13 #include<functional>
14 #include<numeric>
15 #include<utility>
16 #include<sstream>
17 #include<iostream>
18 #include<iomanip>
19 #include<cstdio>
20 #include<cmath>
21 #include<cstdlib>
22 #include<cstring>
23 #include<ctime>
24 #define LL long long 
25 using namespace std;
26 #define M 1000000007
27 LL dpy[1002][2155];
28 LL dpx[1002][2155];
29 int a[1002];
30 
31 int main(){
32     int t; 
33     scanf("%d",&t);
34     while(t--)
35     {
36         int n; 
37         scanf("%d",&n);
38         memset(dpy,0,sizeof(dpy));
39         memset(dpx,0,sizeof(dpx));
40         int temp ; 
41         for(int i = 1;i <= n;i ++)
42         {
43             scanf("%d",&a[i]);
44             dpy[i][a[i]] = 1; 
45             for(int j = 0;j <= 1050;j ++)
46             { 
47                 if(dpy[i-1][j])
48                 {
49                     dpy[i][j] =(dpy[i][j]+dpy[i-1][j])%M;
50                     dpy[i][j^a[i]] = (dpy[i][j^a[i]]+dpy[i-1][j]) % M; 
51                 }
52             }
53         }
54         LL ans = 0 ; 
55         for(int i = n;  i >= 2 ;i -- )
56         {
57             dpx[i][a[i]] = 1 ; 
58             ans = (ans+dpy[i-1][a[i]])% M;
59             int tsum[1058];
60             memset(tsum,0,sizeof(tsum));
61             for(int j = 0 ;j <= 1048;j ++)
62             {
63                 if(dpx[i+1][j])
64                 {
65                     ans = (ans + dpy[i-1][j&a[i]]*dpx[i+1][j])%M;
66                     tsum[j&a[i]] = (tsum[j&a[i]] + dpx[i+1][j]) % M;
67                 }
68             }
69             for(int j = 0;j <= 1050 ;j ++)
70                 dpx[i][j] = (dpx[i+1][j] + dpx[i][j] + tsum[j])%M;
71         }
72         printf("%I64d
",ans%M); 
73     }
74     return 0;
75 }
View Code
没有梦想,何谈远方
原文地址:https://www.cnblogs.com/zyue/p/3881481.html