【2018百度之星資格賽】1001 調查問卷


題意

度度熊為了完成畢業論文,需要收集一些數據來支撐他的論據,於是設計了一份包含 mmm 個問題的調查問卷,每個問題只有 'A' 和 'B' 兩種選項。

將問卷散發出去之后,度度熊收到了 nnn 份互不相同的問卷,在整理結果的時候,他發現可以只保留其中的一部分問題,使得這 nnn 份問卷仍然是互不相同的。這里認為兩張問卷是不同的,當且僅當存在至少一個被保留的問題在這兩份問卷中的回答不同。

現在度度熊想知道,存在多少個問題集合,使得這 nnn 份問卷在只保留這個集合的問題之后至少有 kkk 對問卷是不同的。

分析

本來聽說資格賽做一個題就行,過了簽到后就去睡覺了,醒了后聽說這比賽的評測雞跑的賊快,就瞎搞了一發a,然后··就過了?????

思路就是··用狀態壓縮瞎搞一下。

f[i][S]表示前i個問卷,問題集合是二進制表示的S,有多少對不同的問卷。

f[i][S]=f[i-1][S]+i-(前i里有多少和第i個問卷S問題相同的問卷數目)

就醬

下面是代碼

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 const int maxn=1000+100;
 8 
 9 int T,n,m,k;
10 char s[maxn][15];
11 int f[maxn][1<<11];
12 int vis[maxn];
13 int main(){
14     scanf("%d",&T);
15     for(int t=1;t<=T;t++){
16         printf("Case #%d: ",t);
17         scanf("%d%d%d",&n,&m,&k);
18         for(int i=1;i<=n;i++)
19             scanf("%s",s[i]);
20         for(int ss=0;ss<(1<<m);ss++){
21             memset(vis,0,sizeof(vis));
22             for(int i=1;i<=n;i++){
23                 int S=0;
24                 for(int j=0;j<m;j++){
25                     if(ss&(1<<j)&&s[i][j]=='A'){
26                         S|=(1<<j);
27                     }
28                 }
29                 vis[S]++;
30                 f[i][ss]=f[i-1][ss]+i-vis[S];
31             }
32         }
33         int ans=0;
34         for(int i=0;i<(1<<m);i++){
35             if(f[n][i]>=k)
36                 ans++;
37         }
38         printf("%d\n",ans);
39     }   
40 return 0;
41 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM