【AT2370】Piling Up

題目

有紅藍球各無限多個,初始時任意從中選擇 n 個放入盒子。
初始有一個空的序列,接下來依次做 m 組操作,每組操作爲依次執行下述三個步驟:
(1)從盒子中取出任意一個球插入序列尾;
(2)往盒子中放入紅藍各一個球;
(3)從盒子中取出任意一個球插入序列尾;
m 次操作後,有多少種可能的不同顏色序列,答案對 109+7 取模。

解法:動態規劃

fi,j 表示 i 次操作後盒中剩餘 j 個紅球,則剩餘 nj 個藍球。按照當前取出的兩個球的顏色分類討論,有四種轉移方式:

{fi,jfi,j1(j>0)fi,jfi,j(j>0)fi,jfi,j(j<n)fi,jfi,j+1(j<n)

然後這樣算顯然會有重複,至於去重嘛。。聽大佬說只要做兩遍dp, Ans=dp(n,m)dp(n1,m) 。(證明之類的,挖個坑再說23333)

代碼

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const long long p=1000000007ll;
long long f[3001][3001];
int n,m;

long long dp(int n,int m){
    memset(f,0,sizeof(f));
    for(int i=0;i<=n;++i)f[0][i]=1ll;
    for(int i=1;i<=m;++i)for(int j=0;j<=n;++j){if(j)(f[i][j]+=f[i-1][j]+f[i-1][j-1])%=p;if(j<n)(f[i][j]+=f[i-1][j]+f[i-1][j+1])%=p;}
    long long res=0ll;for(int i=0;i<=n;++i)(res+=f[m][i])%=p;return res;
}

int main(){
    scanf("%d%d",&n,&m);
    printf("%lld",(dp(n,m)-dp(n-1,m)+p)%p);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章