1. 程式人生 > >校內模擬賽:確定小組

校內模擬賽:確定小組

輸出 長度 mes ring size 方案 soft 輸入 log

【問題描述】

有n個人坐成一排,這n個人都在某一個小組中,同一個小組的所有人所坐的位置一定是連續的。

有一個記者在現場進行采訪,他每次采訪都會詢問一個人其所在的小組有多少人,被詢問的每個人都給出了正確的答案,但是由於時間倉促,記者不一定詢問了每個人,我們記錄一個長度為n的答案序列,序列的第i個數表示第i個人的回答,如果為0則表示記者沒有詢問過這個人。

記者發現,對於一些情況,他可以唯一確定這排所有人的分組,而對於另外一些情況則不能,於是記者開始好奇,對於某一個答案序列,他能不能做到這一點,如果能的話輸出1,否則輸出0。

【數據規模與約定】

對於20%的數據,有1<=n<=15,

對於50%的數據,有1<=n<=100,

對於100%的數據,有1<=n<=1000,1<=T<=50,輸入數據中每個答案序列一定由某一組合法的座位分配方案生成。

題解

設f[i]=到i人為止的可行的方案數,然後枚舉i人組內人數j,在j可行的情況下,f[i]=sigma(f[i-j])。

由於判斷可行性所以f[i]>=2時的意義相同,一律保存為2即可。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace
std; 5 int T,n,a[1005]; 6 int solve() 7 { 8 int f[1005]; 9 memset(f,0,sizeof(f)); 10 f[0]=1; 11 for(int i=1 ; i<=n ; ++i ) 12 for(int j=i,x=0 ; j>=1 ; --j) 13 { 14 if(a[j]) 15 { 16 if(x&&a[j]!=x)break; 17 else
x=a[j]; 18 } 19 if(x==0||i-j+1==x) 20 { 21 f[i]=min(2,f[j-1]+f[i]); 22 if(f[i]==2)break; 23 } 24 } 25 if(f[n]==1)return 1; 26 return 0; 27 } 28 int main() 29 { 30 scanf("%d",&T); 31 while(T--) 32 { 33 scanf("%d",&n); 34 for(int i=1 ; i<=n ; ++i) 35 scanf("%d",&a[i]); 36 printf("%d",solve()); 37 } 38 return 0; 39 }

校內模擬賽:確定小組