T1 疾病管理
裸得不能再裸的状压dp 不过数据范围骗人
考试时k==0的点没过 我也很无奈呀qwq
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
int g[2000],f[1<<17];
int pd(int x){
int tot=0;
while (x){
if (x&1) tot++;
x>>=1;
}
return tot;
}
int main(){
freopen ("disease.in","r",stdin);
freopen ("disease.out","w",stdout);
int n,d,k,sum=0;
scanf ("%d%d%d",&n,&d,&k);
for (int i=1;i<=n;++i){
int x,y;
scanf ("%d",&x);
if (x==0) sum++;
for (int j=1;j<=x;++j){
scanf ("%d",&y);
g[i]|=(1<<y-1);
}
}
for (int i=1;i<(1<<d);++i)
{
if (pd(i)<=k)
for (int j=1;j<=n;++j){
if (g[j]&(~(g[j]&i))) continue;
//如果这个公牛的疾病未完全被包含在此状态中 就跳过
f[i]++;
}
}
int ans=0;
for (int i=1;i<(1<<d);++i) ans=max(ans,f[i]);
if (k==0) ans=max(ans,sum);
cout<<ans;
return 0;
}
T2 安排公牛
考场上玄学dfs胡乱搞到70
然而大家似乎都是随手就80了(无奈脸x2
看到<=20的友好范围想着要状压 然而 越想越复杂了(老毛病
正解依旧dp
要注意0也是一种状态 对 什么都不放也是一种状态qwq
大概就是类似于“无即万物“的思想
感谢超级厉害的csy大佬不嫌我蠢跟我讲了几遍
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<string>
#define ll long long
using namespace std;
int x[30][30];
int dp[1<<20];
int n,m,ans=0;
int main(){
freopen ("examnine.in","r",stdin);
freopen ("examnine.out","w",stdout);
scanf ("%d%d",&n,&m);
int sum=0;
for (int i=1;i<=n;++i){
int xx,y;
scanf ("%d",&xx);
for (int j=1;j<=xx;++j){
scanf ("%d",&y);
x[i][y]=1;
}
}
dp[0]=1;
for (int i=1;i<=n;++i)
for (int j=(1<<m)-1;j>=0;--j){
if (!dp[j]) continue;
for (int k=1;k<=m;++k){
if (!x[i][k]) continue;
if (j&(1<<k-1)) continue;
dp[j|(1<<k-1)]+=dp[j];
}
dp[j]=0;
}
for (int i=0;i<=(1<<m)-1;++i) ans+=dp[i];
cout<<ans;
return 0;
}
总结:
以后碰到感觉不怎么好打的dp
一定要认真分析时间复杂度
敢于dfs(逃