1. 程式人生 > >經典動態規劃之放蘋果(洛谷P2386)

經典動態規劃之放蘋果(洛谷P2386)

傳送門

題目背景

(poj1664)

題目描述

把M個同樣的蘋果放在N個同樣的盤子裡,允許有的盤子空著不放,問共有多少種不同的分發(5,1,1和1,1,5是同一種方法)

輸入輸出格式

輸入格式:

第一行是測試資料的數目t(0 <= t <= 20),以下每行均包括二個整數M和N,以空格分開。1<=M,N<=10

輸出格式:

對輸入的每組資料M和N,用一行輸出相應的K。

輸入輸出樣例

輸入樣例#1: 
1
7 3
輸出樣例#1: 
8
輸入樣例#2:
 
3
3 2
4 3
2 7
輸出樣例#2: 
2
4
2

當沒有蘋果時為一種情況,當只有一個盤子時也有一種情況。(全放與不放)

1.若a<b,則必定有b-a個盤子空著 f[a][b]=f[a][a]

若a>b分兩種情況。1.若 a個蘋果放入b-1個盤子裡,有一個為空。f[a][b]=f[a][b-1];

2.若沒有空盤子,則從每個盤子中拿出一個蘋果對方案無影響。f[a][b]=f[a-b][b] ;

方案數等於兩者之和 (不斷向外拿,定會有空盤子出現,然後轉移至情況1)。

遞推法:

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
//XHLRC
using namespace std;
int f[11][11]={0},n,m;

void XHN()
{
memset(f,0,sizeof("f"));
for(int i=0;i<=n;i++)
for(int j=1;j<=m;j++)
{  
if(j==1||i==0)f[i][j]=1;
else if(i<j)f[i][j]=f[i][i];
else f[i][j]=f[i-j][j]+f[i][j-1]; } cout<<f[n][m]<<endl; } int main(){ int num; scanf("%d",&num); while(num--) { scanf("%d%d",&n,&m); XHN(); } }