zoukankan      html  css  js  c++  java
  • 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 }
    View Code

     

  • 相关阅读:
    博客园 投放 谷歌广告(google adsense) 且不被屏蔽掉
    JAVA与C#程序调用DOS命令
    redhat 5 安装apache 2.2
    解决"Windows 安装程序不允许从远程桌面连接安装"
    测试使用windows live writer的adsense coder发布文章
    解决:apache 整合redmine 启动报错 mod_passenger.so: failed to map segment from shared object: Permission denied
    企业级安全服务权限控制 Acegi安装系统介绍 Spring Framework安全系统
    解决Rails升级问题
    解决MyEclipse 7开发EXTJS 每次保存都要编译js的导致开发效率很低的问题
    解决:redmine 安装 rake db:migrate encoding: utf8
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3883654.html
Copyright © 2011-2022 走看看