DIV2 1000pt

题意:给定整数n和r,求有多少个这样的数列,a1,a2...an,使得a1 + a2 +...+an = a1|a2|a3|...|an,(按位或)。输出这样数列的个数mod 1000000009。

   n <= 10,r <= 15000。

解法:先按位分析这道题,若将a1,a2..an转化成二进制形式并对齐如下,则可将题目转化为求每一列最多含有一个1,每一行所对应的数小等于r的矩阵有多少个。

                       

   这样的话,下意识地想到用状态压缩的DP来做,但是这样做的时间复杂度为O(10×15000×15000),不能接受。最后我也没想出更好的方法,只好看了题解。

   对于某一行,若要使得它对应的数小于r,只需要在某一列,r的二进制形式为1,它为0;在这一列之前, 该行所有值与r相同;在这之后,该行每一列可以为任意值。

   设数组d[i][j]表示从左向右扫描的情况下,从第i位扫到第0位,已经有(n-j)个数小于r的情况下,共有多少个符合题意的数列。具体状态转移方程可以看我得代码,详细的注解见官方题解的代码,http://apps.topcoder.com/wiki/display/tc/SRM+508

tag:dp, good

  1. // BEGIN CUT HERE
  2. /*
  3. * Author: plum rain
  4. * score :
  5. */
  6. /*
  7.  
  8. */
  9. // END CUT HERE
  10. #line 11 "YetAnotherORProblem2.cpp"
  11. #include <sstream>
  12. #include <stdexcept>
  13. #include <functional>
  14. #include <iomanip>
  15. #include <numeric>
  16. #include <fstream>
  17. #include <cctype>
  18. #include <iostream>
  19. #include <cstdio>
  20. #include <vector>
  21. #include <cstring>
  22. #include <cmath>
  23. #include <algorithm>
  24. #include <cstdlib>
  25. #include <set>
  26. #include <queue>
  27. #include <bitset>
  28. #include <list>
  29. #include <string>
  30. #include <utility>
  31. #include <map>
  32. #include <ctime>
  33. #include <stack>
  34.  
  35. using namespace std;
  36.  
  37. #define CLR(x) memset(x, 0, sizeof(x))
  38. #define CLR1(x) memset(x, -1, sizeof(x))
  39. #define PB push_back
  40. #define SZ(v) ((int)(v).size())
  41. #define zero(x) (((x)>0?(x):-(x))<eps)
  42. #define out(x) cout<<#x<<":"<<(x)<<endl
  43. #define tst(a) cout<<#a<<endl
  44. #define CINBEQUICKER std::ios::sync_with_stdio(false)
  45.  
  46. typedef vector<int> VI;
  47. typedef vector<string> VS;
  48. typedef vector<double> VD;
  49. typedef long long int64;
  50. typedef pair<int, int> pii;
  51.  
  52. const double eps = 1e-;
  53. const double PI = atan(1.0)*;
  54. const int maxint = ;
  55. const int mod = ;
  56.  
  57. int r, n;
  58. int64 d[][];
  59.  
  60. int64 rec (int t, int num)
  61. {
  62. if (t == -) return ;
  63.  
  64. int64 &ret = d[t][num];
  65. int tmp = r & ( << t);
  66.  
  67. if (ret != -) return ret;
  68.  
  69. if (num == n){
  70. if (tmp)
  71. return ret = (rec(t-, ) + n * rec(t-, )) % mod;
  72. return ret = rec(t-, num);
  73. }
  74. if (num == ){
  75. if (tmp)
  76. return ret = (rec(t-, ) + rec(t-, ) + (n-) * rec(t-, )) % mod;
  77. return ret = n * rec(t-, ) % mod;
  78. }
  79. return ret = (n+) * rec(t-, ) % mod;
  80. }
  81.  
  82. class YetAnotherORProblem2
  83. {
  84. public:
  85. int countSequences(int N, int R){
  86. r = R; n = N;
  87. CLR1 (d);
  88. return (int)((rec(, n)+mod) % mod);
  89. }
  90.  
  91. // BEGIN CUT HERE
  92. public:
  93. void run_test(int Case) { if ((Case == -) || (Case == )) test_case_0(); if ((Case == -) || (Case == )) test_case_1(); if ((Case == -) || (Case == )) test_case_2(); if ((Case == -) || (Case == )) test_case_3(); }
  94. private:
  95. template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
  96. void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }
  97. //void test_case_0() { int Arg0 = 2; int Arg1 = 15000; int Arg2 = 4628299; verify_case(0, Arg2, countSequences(Arg0, Arg1)); }
  98. void test_case_0() { int Arg0 = ; int Arg1 = ; int Arg2 = ; verify_case(, Arg2, countSequences(Arg0, Arg1)); }
  99. void test_case_1() { int Arg0 = ; int Arg1 = ; int Arg2 = ; verify_case(, Arg2, countSequences(Arg0, Arg1)); }
  100. void test_case_2() { int Arg0 = ; int Arg1 = ; int Arg2 = ; verify_case(, Arg2, countSequences(Arg0, Arg1)); }
  101. void test_case_3() { int Arg0 = ; int Arg1 = ; int Arg2 = ; verify_case(, Arg2, countSequences(Arg0, Arg1)); }
  102.  
  103. // END CUT HERE
  104.  
  105. };
  106.  
  107. // BEGIN CUT HERE
  108. int main()
  109. {
  110. // freopen( "a.out" , "w" , stdout );
  111. YetAnotherORProblem2 ___test;
  112. ___test.run_test(-);
  113. return ;
  114. }
  115. // END CUT HERE

SRM 508(2-1000pt)的更多相关文章

  1. SRM 508 DIV1 500pt(DP)

    题目简述 给定一个大小为 n的序列(n<=10)R,要求你计算序列A0, A1, ..., AN-1的数量,要求A序列满足A0 + A1 + ... + AN-1 = A0 | A1 | ... ...

  2. SRM DIV1 500pt DP

    SRM 501 DIV1 500pt SRM 502 DIV1 500pt SRM 508 DIV1 500pt SRM 509 DIV1 500pt SRM 511 DIV1 500pt SRM 5 ...

  3. TC250专场

    SRM 623 DIV2 1000pt 题意:给出一个最多50*50的矩阵,每个单元可能为'.'.'P'.'A','.'代表空地,你每次操作可以把一个P或者A拿到空地上,求一个最大的含有相同字符的矩形 ...

  4. SRM149 - SRM150(少SRM150-DIV1-LV3)

    SRM 149 DIV2 1000pt 题意: 对于n个人,第i人有pi的钱.将他们分成不超过四个组,每组统一交费x,对每个人,若他拥有的钱超过x则交费,否则不交费.问最多能使这些人交多少钱. 1&l ...

  5. Topcoder 好题推荐

    SRM SRM147 DIV1 1000pt DP SRM148 DIV1 1100pt 递归 SRM149 DIV1 1000pt math SRM150 DIV1 500pt DP SRM469 ...

  6. SRM144 - SRM 148(少144-DIV1-LV3,147-DIV2-LV3)

    SRM 144 DIV 1 500pt tag:组合 题意:彩票中奖.给定n, m,从1-n中选择m个数组成数列a1, a2, a3...am.对于数列{am}分别满足以下条件的概率: (1)数列所有 ...

  7. 记第一次TopCoder, 练习SRM 583 div2 250

    今天第一次做topcoder,没有比赛,所以找的最新一期的SRM练习,做了第一道题. 题目大意是说 给一个数字字符串,任意交换两位,使数字变为最小,不能有前导0. 看到题目以后,先想到的找规律,发现要 ...

  8. SRM 513 2 1000CutTheNumbers(状态压缩)

    SRM 513 2 1000CutTheNumbers Problem Statement Manao has a board filled with digits represented as St ...

  9. SRM 510 2 250TheAlmostLuckyNumbersDivTwo(数位dp)

    SRM 510 2 250TheAlmostLuckyNumbersDivTwo Problem Statement John and Brus believe that the digits 4 a ...

随机推荐

  1. jquery,javascript -设置某一ul下的li下的 a的属性

    //javascriptvar ul = document.getElementById('ul); var as = ul.getElementsByTagName('a'); for(var i ...

  2. post和get的区别?

    1. get是从服务器上获取数据,post是向服务器传送数据.2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到.post是通过H ...

  3. 打造属于前端的Uri解析器

    今天和大家一起讨论一下如何打造一个属于前端的url参数解析器.如果你是一个Web开发工程师,如果你了解过后端开发语言,譬如:PHP,Java等,那么你对下面的代码应该不会陌生: $kw = $_GET ...

  4. 十一、C# 泛型

    为了促进代码重用,尤其是算法的重用,C#支持一个名为泛型的特性. 泛型与模块类相似. 泛型使算法和模式只需要实现一交.而不必为每个类型都实现一次.在实例化的时候,传入相应的数据类型便可. 注:可空值类 ...

  5. hdoj 2041 超级阶梯

    代码: #include <stdio.h>int main(){int n;int i;int m;int count;int dp[50];while(scanf("%d&q ...

  6. Swift中的dispatch_once 单例模式

    以下有三种方法实现单例模式,支持懒初始化和线程安全 全局变量 结构 dispatch_once 全局变量: 这里使用了全局变量而非类变量,是因为不支持类变量 private let _Singleto ...

  7. skip-grant-tables的作用

    skip-grant-tables:非常有用的mysql启动参数(不启动grant-tables授权表) skip-grant-tables:非常有用的mysql启动参数   介绍一个非常有用的mys ...

  8. C#中foreach遍历学习笔记

    using System; using System.Collections; using System.Collections.Generic; using System.Linq; using S ...

  9. const 笔记

    .指向const的指针例如:double a=1.01;const double * b=&a;*b=2.1; //这显然是错误的a=2.1; //这是正确的,a和*b的值都会变成2.01,有 ...

  10. java Active Object模式(下)

    Active Object模式的评价与实现考量 Active Object模式通过将方法的调用与执行分离,实现了异步编程.有利于提高并发性,从而提高系统的吞吐率. Active Object模式还有个 ...