給乙個數字串s和正整數d, 統計s有多少種不同的排列能被d整除(可以有前導0)。例如123434有90種排列能
被2整除,其中末位為2的有30種,末位為4的有60種。
input
輸入第一行是乙個整數t,表示測試資料的個數,以下每行一組s和d,中間用空格隔開。s保證只包含數字0, 1
, 2, 3, 4, 5, 6, 7, 8, 9.
output
每個資料僅一行,表示能被d整除的排列的個數。
sample input
000 1
001 1
1234567890 1
123434 2
1234 7
12345 17
12345678 29
sample output
hint
在前三個例子中,排列分別有1, 3, 3628800種,它們都是1的倍數。
【限制】
100%的資料滿足:s的長度不超過10, 1<=d<=1000, 1<=t<=15
有資料範圍可知,複雜度大約是o(2
n∗d∗
t)
o(2^n*d*t)
o(2n∗d
∗t)(別奇怪我真這麼看出來的= =,坑爹的是還要乘個 n
nn我們先假設各個元素不相同,最後再除掉階乘即可
這種整除的問題,一般都要開一維表示餘數,這樣才能轉移
於是我們令 f[s
][k]
f[s][k]
f[s][k
] 表示當前已選集合為 s
ss ,膜 d
dd 為 k
kk 的排列數。
考慮轉移。我們需要選定乙個元素 i
ii 作為最後加入 s
ss 的數。轉移方程:
f [s
∣(
1<
][(j
∗10+a
[i])
modd
]+=f
[s][
j]
f[s|(1s∣(1
<
][(j
∗10+
a[i]
)mod
d]+=
f[s]
[j]
#include #define n 10
#define ll long long
using namespace std;
ll f[1
int a[15], cnt[15];
int main()
for(i = 0; i < (1 << n); i++)
}} ans = f[(1 << n) - 1][0];
for(i = 0; i < 10; i++)
printf("%d\n", ans);
} return 0;
}
BZOJ 1079 SCOI2008 著色方案
題目 分析 一看就覺得是dp或者直接排列組合公式或者容斥?我就只想到dp的,我們用dp i j 表示前i種顏色,排列出有j對相鄰一樣顏色的方案數。當出現乙個新的顏色時,我們把這個顏色插板法插進去,我們要列舉插入的方式,可能插到相鄰顏色一樣的中間,或者不是,然後進行狀態轉移.具體看 include i...
BZOJ1066 SCOI2007蜥蜴 最大流
挺顯然的最大流,源向所有有蜥蜴的點連inf邊,所有點拆成入點和出點,入店向出點連流量為高度的邊,限制流量,所有可以一步跳出去的點向匯連inf邊,跑最大流就行了。include include include define inf 99999999 define maxn 1005 using nam...
BZOJ1079 SCOI2008著色方案 DP
只能想到 5 15 的方法。我們要利用起 ci比較小這個性質,f a b c d e last 表示有a 種顏色用了1個,b種顏色用了2個 上一次染色用的是剩餘 last 個的顏色,轉移就是f a,b,c,d,e,last a last 2 f a 1,b,c,d,e b last 3 f a 1,...