标签:
题意:这题是http://www.cnblogs.com/zyue/p/4436075.html 这题的加强版。
解题思路:根据dp规则,我们可以把d[i]值相同的放到一起,然后算一个总的DP就行了。
解题代码
1 // BEGIN CUT HERE 2 /* 3 4 */ 5 // END CUT HERE 6 /*#line 7 "Nine.cpp" 7 #include <cstdlib> 8 #include <cctype> 9 #include <cstring> 10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13 #include <vector> 14 #include <string> 15 #include <iostream> 16 #include <sstream> 17 #include <map> 18 #include <set> 19 #include <queue> 20 #include <stack> 21 #include <fstream> 22 #include <numeric> 23 #include <iomanip> 24 #include <bitset> 25 #include <list> 26 #include <stdexcept> 27 #include <functional> 28 #include <utility> 29 #include <ctime> 30 using namespace std; 31 32 #define PB push_back 33 #define MP make_pair 34 35 #define REP(i,n) for(i=0;i<(n);++i) 36 #define FOR(i,l,h) for(i=(l);i<=(h);++i) 37 #define FORD(i,h,l) for(i=(h);i>=(l);--i) 38 #define M 1000000007 39 40 typedef vector<int> VI; 41 typedef vector<string> VS; 42 typedef vector<double> VD; 43 typedef long long LL; 44 typedef pair<int,int> PII; 45 46 const int maxn = 9*9*9*9*9; 47 int dp2[5005][10]; 48 int pow9[6]; 49 int dp[maxn][32]; 50 void get_nx() 51 { 52 dp2[0][0] = 1 ; 53 for(int i = 1;i<= 5000 ;i ++) 54 for(int j = 0 ;j <= 9; j ++){ 55 for(int s = 0 ; s <= 9 ; s ++){ 56 dp2[i][(j+s) % 9] = (dp2[i][(j+s) %9] + dp2[i][j]) % M; 57 } 58 } 59 } 60 class Nine 61 { 62 public: 63 int count(int m, vector <int> d){ 64 memset(dp2,0,sizeof(dp2)); 65 get_nx(); 66 memset(dp,0,sizeof(dp)); 67 for() 68 return dp[1][0]; 69 } 70 public: 71 void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); } 72 private: 73 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(); } 74 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; } } 75 void test_case_0() { int Arg0 = 2; int Arr1[] = {1,2}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 4; verify_case(0, Arg2, count(Arg0, Arg1)); } 76 void test_case_1() { int Arg0 = 2; int Arr1[] = {1,2,3}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 16; verify_case(1, Arg2, count(Arg0, Arg1)); } 77 void test_case_2() { int Arg0 = 1; int Arr1[] = {0,0,1}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 200; verify_case(2, Arg2, count(Arg0, Arg1)); } 78 void test_case_3() { int Arg0 = 5; int Arr1[] = {1,3,5,8,24,22,25,21,30,2,4,0,6,7,9,11,14,13,12,15,18,17,16,19,26,29,31,28,27,10,20,23}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 450877328; verify_case(3, Arg2, count(Arg0, Arg1)); } 79 void test_case_4() { int Arg0 = 5; int Arr1[] = {31,31,31,31,31}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 11112; verify_case(4, Arg2, count(Arg0, Arg1)); } 80 81 // END CUT HERE 82 83 }; 84 85 // BEGIN CUT HERE 86 int main() 87 { 88 Nine ___test; 89 clock_t be,en; 90 ___test.run_test(-1); 91 return 0; 92 } 93 94 // END CUT HERE 95 */ 96 97 #include <vector> 98 #include <list> 99 #include <map> 100 #include <set> 101 #include <deque> 102 #include <stack> 103 #include <bitset> 104 #include <algorithm> 105 #include <functional> 106 #include <numeric> 107 #include <utility> 108 #include <sstream> 109 #include <iostream> 110 #include <iomanip> 111 #include <cstdio> 112 #include <cmath> 113 #include <cstdlib> 114 #include <ctime> 115 116 using namespace std; 117 118 class Nine { 119 public: 120 int count(int, vector <int>); 121 }; 122 123 const int md = 1000000007; 124 125 inline void add(int &a, int b) { 126 a += b; 127 if (a >= md) a -= md; 128 } 129 130 inline int mul(int a, int b) { 131 return (long long)a * b % md; 132 } 133 134 int f[33][100010]; 135 int ways[5555][13]; 136 137 int Nine::count(int que, vector <int> d) { 138 int ds = d.size(); 139 for (int i = 0; i <= ds; i++) { 140 for (int j = 0; j < 9; j++) { 141 ways[i][j] = 0; 142 } 143 } 144 ways[0][0] = 1; 145 for (int i = 0; i < ds; i++) { 146 for (int j = 0; j <= 9; j++) { 147 for (int k = 0; k <= 9; k++) { 148 int new_j = (j + k) % 9; 149 add(ways[i + 1][new_j], ways[i][j]); 150 } 151 } 152 }//预处理 多少位 余数为多少的情况数 153 int n = (1 << que); 154 vector <int> cnt(n, 0); 155 for (int i = 0; i < ds; i++) { 156 cnt[d[i]]++; 157 } 158 int MAX = 1; 159 for (int i = 0; i < que; i++) { 160 MAX *= 9; 161 } 162 for (int t = 0; t <= n; t++) { 163 for (int z = 0; z < MAX; z++) { 164 f[t][z] = 0; 165 } 166 } 167 f[0][0] = 1; 168 int cur[42]; 169 for (int t = 0; t < n; t++) { 170 for (int z = 0; z < MAX; z++) {//max代表5个问题的情况压缩 171 int zz = z; 172 for (int i = 0; i < que; i++) { 173 cur[i] = zz % 9; 174 zz /= 9; 175 }//cur[i] 代表的是每一种状态的余数 176 177 for (int now = 0; now <= 9; now++) { //枚举位数 178 179 int new_z = 0; 180 for (int i = que - 1; i >= 0; i--) {//que代表的是问题个数 181 new_z *= 9; 182 int digit = cur[i]; 183 if (t & (1 << i)) { 184 digit += now; 185 if (digit >= 9) digit -= 9; 186 } 187 // 188 new_z += digit; 189 } 190 add(f[t + 1][new_z], mul(f[t][z], ways[cnt[t]][now]));//其实是一下加 cnt[t] 个值 191 } 192 } 193 } 194 return f[n][0]; 195 } 196
标签:
原文地址:http://www.cnblogs.com/zyue/p/4438781.html