拆數遊戲dp
阿新 • • 發佈:2018-12-04
歡迎訪問鄭州大學程式設計線上評測系統(ZZUOJ)! ZZUACM招新群號:562888278
問題4317--有趣的拆數遊戲
4317: 有趣的拆數遊戲
時間限制: 1 Sec 記憶體限制: 128 MB
提交: 28 解決: 8
[提交] [狀態] [討論版] [命題人:admin]
題目描述
Zxy 特別喜歡數學,他看到過許多有趣的拆數題,比如:把一個數拆成兩個質數的和或者將一個數拆成若干個數的和,使得它們的乘積最大,當然這些都是簡單的的問題了,對於熱愛演算法競賽並且足夠優秀的你,當然不用解決這些簡單的問題啦。
現在zxy需要有一個拆數問題交給你。
對於一個整數n,你可以將它拆成若干個數的和,例如
1: {1}
2: {1+1, 2}
3: {1+1+1, 1+2, 2+1, 3}
4: {1+1+1+1, 1+1+2, 1+2+1, 1+3, 2+1+1, 2+2, 3+1, 4}
注意:同樣的集合元素順序不同,我們也認為它們是不同的!
zxy想要統計到底有多少種拆分整數n的方法,所以一個個寫下所有的可能,zxy的隊友孫剛來趁zxy不注意就把一些方案擦去了,zxy很生氣但是又沒有辦法。他發現擦去的集合都有一些特點,就是這個集合的元素裡面含有偶數。
例如對於1,2,3,4剩下的拆分方法是:
1: {1}
2: {1+1}
3: {1+1+1, 3}
4: {1+1+1+1, 1+3, 3+1}
zxy突然靈機一閃,想知道對於一個整數
輸入
第一行一個整數T(T<= 60),代表測試樣例的數量
一個樣例包括一行包含三個整數 n,m,k( 1<=n<=30,0<=m,k<30)
輸出
T行,每行輸出當前組資料拆分方法的數量
樣例輸入
3
10 0 2
15 1 4
28 3 7
樣例輸出
55
235
18848806
#include <bits/stdc++.h>
using namespace std;
const int maxn=31;
int dp[maxn];
int n,m,k,T;
bool check(int x)
{
if((x-m)%k) return true;
else return false;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&k);
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
if(check(j)) dp[i]+=dp[i-j];
}
}
printf("%d\n",dp[n]);
}
return 0;
}