标签:
题意:要你构造一个n位的数子 ,给你m(1-5)个询问,每一次询问取一些位数的数组成一个新数且这个数 %9 == 0 , 问你要满足这m个询问的数字有多少个(允许前缀0)。
解题思路:把每一种情况状压,得到一个最多 9x9x9x9x9 的情况,然后根据 每个数的询问决定状态转移方程。
解题代码:
1 // BEGIN CUT HERE 2 /* 3 4 */ 5 // END CUT HERE 6 #line 7 "NineEasy.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 39 typedef vector<int> VI; 40 typedef vector<string> VS; 41 typedef vector<double> VD; 42 typedef long long LL; 43 typedef pair<int,int> PII; 44 45 #define M 1000000007 46 const int MaxS = 9*9*9*9*9*2; 47 48 long long dp[MaxS][25]; 49 long long pow9[6]; 50 51 class NineEasy 52 { 53 public: 54 int count(int m, vector <int> d) 55 { 56 memset(dp,0,sizeof(dp)); 57 pow9[0] = 1; for(int i = 1;i <= 5;i ++) pow9[i] = pow9[i-1] * 9 ; 58 int n = d.size(); 59 dp[0][0] = 1; 60 for(int i = 0 ;i < n; i ++){ 61 for(int j = 0 ;j < pow9[m]; j ++){ 62 for(int p = 0 ;p <= 9 ; p ++){ 63 int ns = 0; 64 for(int s = 0 ; s < m ; s ++){ 65 if((1 << s ) & d[i]){ 66 ns += ((j/pow9[s] + p )%9)*pow9[s] ; 67 }else{ 68 ns += ((j/pow9[s])%9)*pow9[s]; 69 } 70 } 71 dp[ns][i+1] = (dp[ns][i+1] + dp[j][i]) % M; 72 } 73 } 74 } 75 return dp[0][n]; 76 } 77 78 // BEGIN CUT HERE 79 public: 80 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(); } 81 private: 82 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(); } 83 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; } } 84 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)); } 85 void test_case_1() { int Arg0 = 2; int Arr1[] = {3,3}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 12; verify_case(1, Arg2, count(Arg0, Arg1)); } 86 void test_case_2() { int Arg0 = 2; int Arr1[] = {1,3,2}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 16; verify_case(2, Arg2, count(Arg0, Arg1)); } 87 void test_case_3() { int Arg0 = 5; int Arr1[] = {1,2,4,8,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 893703876; verify_case(3, Arg2, count(Arg0, Arg1)); } 88 void test_case_4() { int Arg0 = 1; int Arr1[] = {0,0,1}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arg2 = 200; verify_case(4, Arg2, count(Arg0, Arg1)); } 89 90 // END CUT HERE 91 92 }; 93 94 // BEGIN CUT HERE 95 int main() 96 { 97 NineEasy ___test; 98 ___test.run_test(-1); 99 return 0; 100 } 101 // END CUT HERE
Topcoder SRM655 DIV2 950 NineEasy 状压 + 数位 dp
标签:
原文地址:http://www.cnblogs.com/zyue/p/4433054.html