[USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins
阿新 • • 發佈:2018-12-13
連結
大意
給定 種維生素的需求量,對於第 種維生素的需求量,記為
給定 種飼料,對於第 種飼料的第 種維生素,其能增加 點維生素
問最少需要幾個飼料,如果有多組解,輸出最小的那個。
資料範圍:
思路
觀察資料範圍發現 很小,於是我們可以 或者狀態壓縮,本人用的是狀態壓縮。
我們狀壓 個飼料的使用情況,然後進行判斷,由於我們選擇的順序是從小到大的,所以自然字典序也是最小的,就不需要判斷了。
判斷使用了幾種飼料的過程可以直接用迴圈判斷,也可以用 操作,兩種判斷方法的時間複雜度都是 , 常數會小很多
總時間複雜度
程式碼
/*
ID:hzbismy1
LANG:C++
TASK:holstein
*/
#define file(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout)
#include<cstdio>
#include<cctype>
#include<cstring>
using namespace std;int n,a[36],b[25][25],m,ansk,ansi,k,s[25];
inline char Getchar()
{
static char buf[100000],*p1=buf+100000,*pend=buf+100000;
if(p1==pend)
{
p1=buf; pend=buf+fread(buf,1,100000,stdin);
if (pend==p1) return -1;
}
return *p1++;
}
inline int read()
{
char c;int d=1,f=0;
while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline void write(register long long x)
{
if(x<0)write(45),x=-x;
if(x>9)write(x/10);
putchar(x%10+48);
return;
}//以上為讀入輸出優化
inline int getk(register int x)//獲得x種1的個數
{
int ans=0;
while((x&-x)!=0)//lowbit操作
{
ans++;
x-=x&-x;
}
return ans;
}
inline bool check()//判斷能否滿足需求
{
for(register int i=1;i<=n;i++) if(s[i]<a[i]) return false;
return true;
}
signed main()
{
n=read();
for(register int i=1;i<=n;i++) a[i]=read();
m=read();ansk=m+1;//記得初始化
for(register int i=1;i<=m;i++) for(register int j=1;j<=n;j++) b[i][j]=read();
for(register int i=1;i<(1<<m);i++)
{
memset(s,0,sizeof(s));//記得清空
for(register int j=0;j<m;j++)
if((i>>j)&1) for(register int l=1;l<=n;l++) s[l]+=b[j+1][l];//如果選了則加上
if(check())//合法
{
k=getk(i);
if(k<ansk)//個數更少
{
ansi=i;
ansk=k;
}
}
}
write(ansk);for(register int i=0;i<m;i++) if((ansi>>i)&1) putchar(32),write(i+1);//輸出
putchar(10);//沒有這行就會愉快的被USACO卡
}