1. 程式人生 > >洛谷P1641 [SCOI2010]生成字串 解題報告

洛谷P1641 [SCOI2010]生成字串 解題報告

題面

lxhgww最近接到了一個生成字串的任務,任務需要他把n個1和m個0組成字串,但是任務還要求在組成的字串中,在任意的前k個字元中,1的個數不能少於0的個數。現在lxhgww想要知道滿足要求的字串共有多少個,聰明的程式設計師們,你們能幫助他嗎?

輸入輸出格式

輸入格式:

輸入資料是一行,包括2個數字n和m

輸出格式:

輸出資料是一行,包括1個數字,表示滿足要求的字串數目,這個數可能會很大,只需輸出這個數除以20100403的餘數

輸入輸出樣例

輸入樣例#1: 2 2 輸出樣例#1: 2

說明

對於30%的資料,保證1<=m<=n<=1000

對於100%的資料,保證1<=m<=n<=1000000


 

本題解主要為讓本蒟蒻理清思路,因此在敘述上可能會有些繁瑣orz

首先我們分析一下題目要求,用n個1和m和0組成字串,且截至到任意位置,1的個數一定大於等於0的個數。

我們考慮建立一個平面直角座標系,x座標軸表示1和0的個數和,y座標軸表示1和0的個數差

因此只要選一個新的數字,就是向右走。若選擇0就是向右下(1的個數減去0的個數變少了一個),同理選擇1就是向右上走(1的個數減去0的個數增加)。

由於直接求合法方案數比較困難,所以先求出全部方案數再減去不合法方案數。

  • 全部方案數:從(0,0)點走到(n+m,n-m)點的個數。即選擇了全部n+m個數字,1的個數比0的個數恰好多了n-m個。

   即從n+m個數中選擇了n個1——C(n+m,n)或C(n+m,m)。

  • 再考慮不合法方案數,任意一點的 1個數減0個數 小於零,即經過 y=-1 這條線的情況全部不合法。

   利用等效替代法:

     我們把不合法的情況在經過 y=-1 這條線之前的線以 y=-1 為對稱軸向下翻折。起點就變成了 (0,-2),終點仍然是 (n+m,n-m)。

     再沿y軸向上平移2個單位,即從(0,0)走到(n+m,n-m+2),即選擇n+1個1,m-1個0。

   故不合法方案數等於C(n+m,n+1)。

答案即  C(n+m,n) - C(n+m,n+1)。


 

程式碼如下

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 
 5 const int p=20100403;
 6 int n,m;
 7 const int N=1e6+5;
 8 ll jc[N<<1];
 9 
10 inline ll ksm(ll a,ll b)
11 {
12     ll ans=1;
13     while(b)
14     {
15         if(b&1) ans=(ans*a)%p;
16         a=(a*a)%p;
17         b>>=1;
18     }
19     return ans;
20 }
21 
22 inline ll C(int a,int b)
23 {
24     return jc[a]*ksm(jc[a-b]*jc[b]%p,p-2)%p;
25 }
26 
27 int main()
28 {
29     scanf("%d%d",&n,&m);
30     jc[1]=1;
31     for(int i=2;i<=m+n;i++)
32     {
33         jc[i]=jc[i-1]*i%p;
34     }
35     cout<<(C(n+m,m)-C(n+m,m-1)+p)%p;
36 }
View Code

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int p=20100403;
int n,m;
const int N=1e6+5;
ll jc[N<<1];

inline ll ksm(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1) ans=(ans*a)%p;
a=(a*a)%p;
b>>=1;
}
return ans;
}

inline ll C(int a,int b)
{
return jc[a]*ksm(jc[a-b]*jc[b]%p,p-2)%p;
}

int main()
{
scanf("%d%d",&n,&m);
jc[1]=1;
for(int i=2;i<=m+n;i++)
{
jc[i]=jc[i-1]*i%p;
}
cout<<(C(n+m,m)-C(n+m,m-1)+p)%p;
}