穿越栅栏这题是一道 DFS题,但觉得DFS代码太长,就写了投机取巧代码。
这个技巧就是,用位运算,呃呃呃,这么说吧,我现在有一个二进制的数,这个数有g位,第i位数字为1是,表示用这种饲料,0表示不用,这样一来,就只要枚举从0~1(<<)g位了,代码会短很多,时间复杂度也并不见得比DFS要慢。
上代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
int need[100],num[100][100],h[100],n,g;
int count(int n)
{
int ans = 0;
while(n!=0)
{
if(n%2==1)ans++;
n >>= 1;
}
return ans;
}
bool cmp(int x)
{
int i = 0;
while(x!=0)
{
if(x%2==0){x >>= 1;i++;continue; }
for(int j = 0;j<n;j++)h[j] += num[i][j];
x >>= 1;i++;
}
for(int i = 0;i<n;i++)
if(need[i]>h[i])return false;
return true;
}
int main()
{
freopen("holsteins.in","r",stdin);
freopen("holsteins.out","w",stdout);
std::cin>>n;
for(int i = 0;i<n;i++)std::cin>>need[i];
std::cin>>g;
for(int i = 0;i<g;i++)
for(int j = 0;j<n;j++)
std::cin>>num[i][j];
int ans = (1<<30)-1;
for(int i = 0;i<(1<<g);i++)
{
for(int i = 0;i<n;i++)h[i] = 0;
if(cmp(i)==false)continue;
ans = count(ans)<=count(i)?ans:i;
}
memset(h,0,sizeof(h));
int i = 1;
std::cout<<count(ans)<<" ";
while(ans!=0)
{
if(ans%2==0){ans >>= 1;i++;continue;}
std::cout<<i<<" ";
ans >>= 1;i++;
}
fclose(stdin);
fclose(stdout);
return 0;
}