Lightoj 1021 Painful Bases (狀壓dp 有趣)
Time Limit: 2 second(s) | Memory Limit: 32 MB |
As you know that sometimes base conversion is a painful task. But still there are interesting facts in bases.
For convenience let's assume that we are dealing with the bases from 2 to 16. The valid symbols are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E and F. And you can assume that all the numbers given in this problem are valid. For example 67AB is not a valid number of base 11, since the allowed digits for base 11 are 0 to A.
Now in this problem you are given a base, an integer K and a valid number in the base which contains distinct digits. You have to find the number of permutations of the given number which are divisible by K. K is given in decimal.
For this problem, you can assume that numbers with leading zeroes are allowed. So, 096 is a valid integer.
Input
Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case starts with a blank line. After that there will be two integers, base (2 ≤ base ≤ 16) and K (1 ≤ K ≤ 20). The next line contains a valid integer in that base which contains distinct digits, that means in that number no digit occurs more than once.
Output
For each case, print the case number and the desired result.
Sample Input |
Output for Sample Input |
3
2 2 10
10 2 5681
16 1 ABCDEF0123456789 |
Case 1: 1 Case 2: 12 Case 3: 20922789888000 |
題目連結:http://lightoj.com/volume_showproblem.php?problem=1021
題目大意:base表示base進位制,給一個k(0 <= k <= 20),給一個base進位制下的合法數,保證每位數字都不同,求這個數字的所有排列中是k的倍數的個數
題目分析:因為數字都不同,所以最多隻有16位,因此可以狀壓做,dp[i][j]表示選數狀態為i,模k為j的排列數個數,然後對一個合法狀態擴充套件就是在前面加數字,取模的時候因為((x * base) + num[idx]) % k == ((x * base) % k + num[idx] % k) % k == (j * base + num[idx] % k ) % k所以轉移方程就是
dp[i | (1 << idx)][(j * base + num[idx] % k) % k] += dp[i][j]
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
int const MAX = (1 << 16) + 5;
ll dp[MAX][25];
char s[25];
int num[25];
int main()
{
int T;
scanf("%d", &T);
for(int ca = 1; ca <= T; ca++)
{
int b, k;
scanf("%d %d", &b, &k);
scanf("%s", s);
int len = strlen(s);
memset(dp, 0, sizeof(dp));
for(int i = 0; i < len; i++)
num[i] = s[i] >= 'A' ? (10 + s[i] - 'A') : (s[i] - '0');
dp[0][0] = 1;
for(int i = 0; i < (1 << len); i++)
for(int j = 0; j < k; j++)
if(dp[i][j])
for(int idx = 0; idx < len; idx++)
if(!(i & (1 << idx)))
dp[i | (1 << idx)][(j * b + num[idx] % k) % k] += dp[i][j];
printf("Case %d: %lld\n", ca, dp[(1 << len) - 1][0]);
}
}
相關文章
- 狀壓 dp
- 狀壓DP
- 狀壓DP基礎入門
- 合理安排(狀壓dp,包括技巧)
- E - Remove Pairs(狀壓dp+博弈論)REMAI
- Uva-1633 Dyslexic Gollum(狀壓DP)Go
- HDU 5067 Harry And Dig Machine(狀壓dp)Mac
- 演算法學習之路|狀態壓縮dp演算法
- bzoj 3812: 主旋律 [容斥原理 狀壓DP]
- Codeforces Round #321 (Div. 2) D 狀壓dp
- ZOJ 3802 Easy 2048 Again(狀壓dp)AI
- 分組(狀壓dp+技巧:快速列舉子集)
- lightoj 1030 Discovering Gold (基礎概率dp)Go
- Luogu P1777 幫助 題解 [ 紫 ] [ 線性 dp ] [ 狀壓 dp ]
- NOIP2005過河[DP 狀態壓縮]
- POJ 3254 Corn Fields:網格密鋪類 狀壓dp
- Codeforces 11D A Simple Task 題解 [ 藍 ] [ 狀壓 dp ]
- POJ 2411 Mondriaan's Dream:網格密鋪類 狀壓dp
- URAL 1152 False Mirrors(簡單的狀態壓縮dp)False
- Codeforces 327E Axis Walking (狀壓dp lowbit優化)優化
- CF79D Password (差分+狀壓 dp+最短路/bfs)
- 一類哈密頓路徑/迴路為背景的狀壓dp
- Codeforces 895C Square Subsets:狀壓dp【組合數結論】
- HDU 5135 Little Zu Chongzhi's Triangles(狀壓dp或者貪心)
- HDU 1992Tiling a Grid With Dominoes(狀壓dp)
- UVA 11825 dp、狀態壓縮、二進位制法表示集合
- hdu3001 狀態壓縮dp+三進位制
- 動態規劃——用二進位制表示集合的狀態壓縮DP動態規劃
- [狀壓dp]leeccode1434:每個人戴不同帽子的方案數(hard)
- Codeforces 453B Little Pony and Harmony Chest:狀壓dp【記錄轉移路徑】
- lightoj 1031 - Easy Game 【區間dp】360 2017筆試程式設計題3GAM筆試程式設計
- 互不侵犯 (狀壓)
- 2014上海網路賽1004||hdu5045 contest【狀態壓縮dp】
- ACM-ICPC 2018 南京賽區網路預賽__E AC Challenge【狀態壓縮+DP】ACM
- Tips for Navigating Large Game Code BasesGAM
- usering mongotemplate bases on spring-Data-mongoGoSpring
- HDU 4770 Lights Against Dudely(列舉所有狀態 當然壯壓dp會很簡單)AI
- Luogu P5005 中國象棋 - 擺上馬 / Luogu P8756 國際象棋 題解 [ 藍 ] [ 狀壓 dp ] [ 位運算 ]