码迷,mamicode.com
首页 > 其他好文 > 详细

Bzoj1072--Scoi2007排列perm

时间:2016-10-10 21:03:00      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:

一开始sb以为是数位dp,想到状态是十维每维代表每个数字出现次数,再加一维代表余数。空间时间都要炸飞。。。

后来想了想可以直接用数字在原串上出现的位置来代替那十维,结果没有意识到这就是状压dp。。。导致写出来常数爆炸

不过过了就懒得改了。- -

代码看看就可以了:

#include<bits/stdc++.h>
#define LL long long
#define MAXN 20000005
using namespace std;

int dp[15][1030][1005],d,T;
int len,full;
char s[15];

int check(int v,int st) {
    for(int i=0;i<len;i++) {
        if(s[i]==v&&!(st&(1<<i))) return i;
    }
    return -1;
}

int mdp() {
    for(int t,i=0;i<=9;i++) {
        if((t=check(i+0,0))!=-1) dp[1][1<<t][i%d]++;
    }
    for(int i=2;i<=len;i++) {
        for(int st=0;st<full;st++) 
            for(int k=0;k<d;k++) {
                if(!dp[i-1][st][k]) continue;
                for(int t,j=0;j<=9;j++) {
                    if((t=check(j+0,st))!=-1) dp[i][st|(1<<t)][(k*10+j)%d]+=dp[i-1][st][k];
                }
            }
    }
    return dp[len][full-1][0];
}

int main() {
    scanf("%d",&T);
    for(int i=1;i<=T;i++) {
        scanf("%s%d",s,&d);
        memset(dp,0,sizeof(dp));
        len=strlen(s);full=1<<len;
        printf("%d\n",mdp());
    }
    return 0;
}

 

Bzoj1072--Scoi2007排列perm

标签:

原文地址:http://www.cnblogs.com/ihopenot/p/5946908.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!