bzoj 3668 数位DP

 

收获:

  1、如果有很多位操作,并且不包含+-×/等高级运算,那么可以一位一位考虑,如果求一个最优解,可以尝试逐位确定,这道题因为原始攻击值有范围,那么就需要数位DP。

 

 1 /**************************************************************
 2     Problem: 3668
 3     User: idy002
 4     Language: C++
 5     Result: Accepted
 6     Time:288 ms
 7     Memory:804 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #define max(a,b) ((a)>(b)?(a):(b))
12  
13 int n, m;
14 unsigned past[32][2];
15 unsigned dp[32][2], top[32];
16  
17 int main() {
18     scanf( "%d%d", &n, &m );
19     for( int i=0; i<32; i++ ) {
20         past[i][0] = 0;
21         past[i][1] = 1;
22     }
23     for( int i=1; i<=n; i++ ) {
24         char ch[10];
25         unsigned t;
26         scanf( "%s%d", ch, &t );
27         for( int b=0; b<32; b++ ) {
28             if( ch[0]=='A' ) {
29                 past[b][0] &= (t>>b)&1;
30                 past[b][1] &= (t>>b)&1;
31             } else if( ch[0]=='O' ) {
32                 past[b][0] |= (t>>b)&1;
33                 past[b][1] |= (t>>b)&1;
34             } else {
35                 past[b][0] ^= (t>>b)&1;
36                 past[b][1] ^= (t>>b)&1;
37             }
38         }
39     }
40     if( m==0 ) { 
41         unsigned ans = 0;
42         for( int i=0; i<32; i++ )
43             ans |= past[i][0]<<i;
44         printf( "%u\n", ans );
45     } else {
46         for( int b=0; b<32; b++ ) 
47             top[b] = (m>>b)&1;
48  
49         int maxb=30;
50         while( top[maxb]==0 ) {
51             dp[maxb][1] = dp[maxb][0] = dp[maxb+1][1]|(past[maxb][0]<<maxb);
52             maxb--;
53         }
54         dp[maxb][1] = dp[maxb+1][1]|(past[maxb][1]<<maxb);
55         dp[maxb][0] = dp[maxb+1][1]|(past[maxb][0]<<maxb);
56         for( int i=maxb-1; i>=0; i-- ) {
57             for( int j=0; j<=1; j++ ) 
58                 dp[i][0] = max( dp[i][0], dp[i+1][0]|(past[i][j]<<i) );
59             for( int j=0; j<top[i]; j++ )
60                 dp[i][0] = max( dp[i][0], dp[i+1][1]|(past[i][j]<<i) );
61             dp[i][1] = dp[i+1][1]|(past[i][top[i]]<<i);
62         }
63         printf( "%u\n", max(dp[0][0],dp[0][1]) );
64     }
65 }
View Code

 

posted @ 2015-05-12 21:43  idy002  阅读(297)  评论(0编辑  收藏  举报