校内模拟赛:确定小组

 

【问题描述】

    有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 } 
原文地址:https://www.cnblogs.com/fujudge/p/7523838.html