题目大意
给出一组数和一个G组数
求从G组数中取P组数,使他们的相对应的值相加都大于给定的那一组数
如果有多个解,输出饲料序号最小的(即字典序最小)。
题目解析
利用二进制枚举,即1表示取,0表示不取
把所取得那几组数全加起来,判断是否符合要求,并求最优的解,即字典序最小
代码
#include<bits/stdc++.h>
using namespace std;
//ifstream fin("a.txt");
int n,m,ans=1e9,c;
int g[30][30],v[30],a[30],s[30];
bool flag[30];
bool check()
{
for(int i=1;i<=n;i++)
if(a[i]<v[i])
return false;
return true;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>v[i];
cin>>m;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
cin>>g[i][j];
for(int i=1;i<=(1<<m)-1;i++)//二进制枚举
{
c=0;
memset(flag,0,sizeof(flag));
memset(a,0,sizeof(a));
int ii=i,xx=1,si=0;
int ss[30];
memset(ss,0,sizeof(ss));
while(ii>0)
{
if(ii%2==1) flag[xx]=1;
xx++;
ii/=2;
}//找出取哪组数
for(int j=1;j<=m;j++)
if(flag[j])
{
ss[++si]=j;
c++;
for(int k=1;k<=n;k++)
a[k]+=g[j][k];
}
if(check())//判断是否合法
{
if(c<ans)//求字典序最小的解
{
ans=c;
memcpy(s,ss,sizeof(ss));
}
}
}
cout<<ans<<" ";
for(int i=1;i<=ans;i++)
cout<<s[i]<<" ";//输出
}