light oj 1021 状态压缩dp
2015-08-11 19:40
344 查看
给一个B进制的数,一个10进制的数K,B进制数有x位,对着x位进行全排列的话,有x!种可能,问这x!的可能中,有多少种可以整除K,各个位置上的数字都不同。
代码也是看过题解之后才会写的 QAQ。。。。。。。。
状态压缩dp,每次选一个没有用过的数,然后选一个没有用过的位置放上去,位置不一样,加上的值也不一样,然后直接记录对K取余,余数有多少种。
dp[i][j]表示数位为i(i为1表示数字取了),对K去余为j,有多少种情况。
(j*Base + num[u]) % k,就是表示新组成的数对k去余~
#include <stdio.h>
#include <string.h>
#include <algorithm>
#pragma warning (disable :4996)
using namespace std;
const int Max = 1 << 16;
long long dp[Max][22];
int main()
{
char s[20];
int num[20];
int T;
scanf("%d", &T);
for (int t = 1; t <= T; t++)
{
int base, k;
scanf("%d %d", &base, &k);
scanf("%s", s);
int len = strlen(s);
for (int i = 0; i < len; i++)
{
if (s[i] >= '0'&&s[i] <= '9')
num[i] = s[i] - '0';
else
num[i] = s[i] - 'A' + 10;
}
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for (int i = 0; i < (1 << len); i++)//枚举每一位数位
{
for (int j = 0; j <= k; j++)
{
if (!dp[i][j])continue;
for (int u = 0; u < len; u++)
{
if (i&(1 << u))continue;//i在第u个位置上为1,表示被取过了,不进行运算。
dp[i|(1 << u)][(j*base + num[u]) % k] += dp[i][j];
}
}
}
printf("Case %d: %lld\n", t, dp[(1 << len) - 1][0]);
}
return 0;
}
代码也是看过题解之后才会写的 QAQ。。。。。。。。
状态压缩dp,每次选一个没有用过的数,然后选一个没有用过的位置放上去,位置不一样,加上的值也不一样,然后直接记录对K取余,余数有多少种。
dp[i][j]表示数位为i(i为1表示数字取了),对K去余为j,有多少种情况。
(j*Base + num[u]) % k,就是表示新组成的数对k去余~
#include <stdio.h>
#include <string.h>
#include <algorithm>
#pragma warning (disable :4996)
using namespace std;
const int Max = 1 << 16;
long long dp[Max][22];
int main()
{
char s[20];
int num[20];
int T;
scanf("%d", &T);
for (int t = 1; t <= T; t++)
{
int base, k;
scanf("%d %d", &base, &k);
scanf("%s", s);
int len = strlen(s);
for (int i = 0; i < len; i++)
{
if (s[i] >= '0'&&s[i] <= '9')
num[i] = s[i] - '0';
else
num[i] = s[i] - 'A' + 10;
}
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for (int i = 0; i < (1 << len); i++)//枚举每一位数位
{
for (int j = 0; j <= k; j++)
{
if (!dp[i][j])continue;
for (int u = 0; u < len; u++)
{
if (i&(1 << u))continue;//i在第u个位置上为1,表示被取过了,不进行运算。
dp[i|(1 << u)][(j*base + num[u]) % k] += dp[i][j];
}
}
}
printf("Case %d: %lld\n", t, dp[(1 << len) - 1][0]);
}
return 0;
}
相关文章推荐
- ZOJ2836 Number Puzzle【容斥原理】
- 08-11 数据库、方法封装 Serverlet、doGet方法
- 蓝桥杯-算法训练-最短路
- gcc和g++的区别
- poj 1032 Parliament (整数拆分)
- hdu 3572 Task Schedule(最大流&&建图经典&&dinic)
- [POJ 1679] The Unique MST 最小树
- iOS开发-Day13-OC基础、面向对象
- 从错误中学python(2)————字符串转浮点数
- PAT 1038. Recover the Smallest Number (30)
- 使用java的迭代器对list进行遍历
- windows wim
- eclipse store password unencrypted
- Serverlet搭建
- JavaScript学习笔记5
- MYSQL隔离级别介绍
- #笔记#圣思园 JavaWeb 第65讲——jQuery,选择器
- 《Java开发实战经典》第三章答案3.3
- 机器学习:正则化
- sunburnt 学习笔记 (二) solr配置的简单说明