最多有15种食物,然后对于每种食物有选或者不选两种情况,所以总的情况数只有2^15种,我们可以借助状态压缩,穷举出所有的状态,然后求出最好的情况。
代码如下:
/*
ID: 15674811
LANG: C++
TASK: holstein
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<fstream>
using namespace std;
#define INF 0x3f3f3f3f
int ans[20],cnt;
int v[30],a[20][30],G;
int main()
{
ofstream fout("holstein.out");
ifstream fin("holstein.in");
///ifstream fin("lkl.txt");
int n;
while(fin>>n)
{
cnt=INF;
for(int i=0;i<n;i++)
fin>>v[i];
fin>>G;
for(int i=0;i<G;i++)
for(int j=0;j<n;j++)
fin>>a[i][j];
int k=1<<G;
for(int i=1;i<k;i++)
{
int test[30];
int c=0,j=i;
while(j)
{
if(j&1) c++;
j=j>>1;
}
if(c>cnt)
continue;
int tmp[30];
memset(tmp,0,sizeof(tmp));
j=i;
int t=0;
int m=0;
while(j)
{
if(j&1)
{
test[m++]=t;
for(int d1=0;d1<n;d1++)
tmp[d1]+=a[t][d1];
}
j=j>>1;
t++;
}
int i1=0;
for(i1=0;i1<n;i1++)
if(tmp[i1]<v[i1])
break;
if(i1<n)
continue;
if(c==cnt)
{
int d1,flag=0;
for(d1=0;d1<c;d1++)
if(ans[d1]>test[d1])
{
flag=1;
break;
}
else if(ans[d1]<test[d1])
break;
if(flag)
{
for(d1=0;d1<c;d1++)
ans[d1]=test[d1];
}
}
if(c<cnt)
{
cnt=c;
for(int d1=0;d1<c;d1++)
ans[d1]=test[d1];
}
}
fout<<cnt<<" ";
for(int i=0;i<cnt-1;i++)
fout<<ans[i]+1<<" ";
fout<<ans[cnt-1]+1<<endl;
}
return 0;
}