SRM 597div2 1K

来源:互联网 发布:手机通讯软件作用 编辑:程序博客网 时间:2024/06/05 02:09

题意:n<=1e9

1,2,3,4,5,6.。。n

问你有多少个数字集合,不包含重复的数位

好题

数位dp 预处理 cnt【state】,然后背包

注意11这种,本身重复的也不行

ps:看了下别人的代码,好像满足条件的数并不太多,直接暴力dfs处理出cnt数组也可以

#include <cstdlib>#include <cctype>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>#include <string>#include <iostream>#include <sstream>#include <map>#include <set>#include <queue>#include <stack>#include <ctime>using namespace std;class LittleElephantAndSubset{public:     int getNumber(int N);        // BEGIN CUT HEREpublic: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(); }private: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(); }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; } }void test_case_0() { int Arg0 = 3; int Arg1 = 7; verify_case(0, Arg1, getNumber(Arg0)); }void test_case_1() { int Arg0 = 10; int Arg1 = 767; verify_case(1, Arg1, getNumber(Arg0)); }void test_case_2() { int Arg0 = 47; int Arg1 = 25775; verify_case(2, Arg1, getNumber(Arg0)); }void test_case_3() { int Arg0 = 4777447; int Arg1 = 66437071; verify_case(3, Arg1, getNumber(Arg0)); }// END CUT HERE};// BEGIN CUT HEREint main(){    LittleElephantAndSubset ___test;    ___test.run_test(-1);    return 0;}// END CUT HEREint cnt[1024];bool vis[10];int dig[15];int dp[15][1024];int now;int dfs(int len,bool lim,bool pos,int state) {    if(!len) return pos && state == now;    if(!lim && pos && dp[len][state] != -1) return dp[len][state];    int mx = lim ? dig[len-1] : 9;    int ret = 0;    for(int i = 0; i <= mx; i++) {        if(vis[i]) {            int tmp ;            if(state & (1<<i)) continue;            if(!pos && !i) tmp = state;            else tmp = state | (1<<i);            ret += dfs(len-1,lim&&i==mx,pos||i,tmp);        }    }    if(!lim && pos) dp[len][state] = ret;    return ret;}long long f[1024];int LittleElephantAndSubset::getNumber(int N){    int tot = 0;    for(int t = N; t; t /= 10) dig[tot++] = t%10;    memset(cnt,0,sizeof(cnt));    for(int i = 0; i < 1024; i++) {        memset(vis,false,sizeof(vis));        vis[0] = true;        for(int j = 0; j < 10; j++) if(i >> j & 1) {            vis[j] = true;        }        now = i;        memset(dp,-1,sizeof(dp));        cnt[i] = dfs(tot,true,false,0);    }    memset(f,0,sizeof(f));    f[0] = 1;    for(int state = 1; state < 1024; state++) if(cnt[state]){        for(int i = 0; i < 1024; i++)if(!(i&state)) {            f[i|state] +=( f[i] * cnt[state]%1000000007 );            f[i|state] %= 1000000007;        }    }    int ans = 0;    for(int i = 1; i < 1024; i++) {        ans += f[i];        if(ans >= 1000000007) ans -= 1000000007;    }    return ans;}


原创粉丝点击