频道栏目
首页 > 资讯 > C++ > 正文

[BZOJ 1072][SCOI 2007]排列perm

14-12-06        来源:[db:作者]  
收藏   我要投稿

 

这题范围小,s的长度不超过10,如果用二进制表示每一位数字是否被选择到的话,二进制最大不超过2^10,可以用状压DP做。

我们把这题分两步走

第一步,把输入的字符串s中所有的数字都当成不同的,在这种情况下求出方案总数

用f[S][j]表示当前每一位数字是否选到的二进制状态为S,拼出的数mod d=j的方案数。

决策就是可以从所有没有被选到的数字中,选择一个数放到之前拼好的数字后面,组成新的数。

如果原来的数mod d=j的话,那么很容易想到新的数mod d=(j*10+新加入的数)mod d

第二步,由于我们第一步把所有数字都当成不相同的了,但是这样做相同的数字会造成重复,若数字x(0<=x<=9)在字符串中出现了t次,那么数字x引起重复t!次。

把0~9的所有数字遍历一遍,除掉每个数字造成的重复。

#include 
#include 
#include 
#include 
#include 
 
using namespace std;
 
int d,cnt[11],f[3010][1010]; //f[S][j]=当前选取数字的二进制状态为S,mod d=j的方案数
char s[11];
 
int main()
{
    int T;
    scanf(%d,&T);
    while(T--)
    {
        scanf(%s%d,s,&d);
        int len=strlen(s);
        memset(f,0,sizeof(f));
        memset(cnt,0,sizeof(cnt));
        for(int i=0;i

 

 

 

 

??
相关TAG标签
上一篇:邻接表和邻接矩阵手写简洁代码DFS BFS
下一篇:HDU 1856 More is better (并查集)
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站