http://acm.hdu.edu.cn/showproblem.php?pid=4152
题意:输入n个目标值,输入m*n的矩阵,在m行中尽可能的选取多的行,使这p行对应的数相加后,所有的值都大于对应的目标值。
做法:用深搜的方法,将每一行选还是不选都列举一遍,并且每次搜到m时,都进行一次判断,看其是否满足要求。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m,a[26][30],goal[30],vis[26],ans,tot,end[26];
bool judge()
{
int sum[30],i,j;
memset(sum,0,sizeof(sum));
for(i=1;i<=m;i++)
{
if(vis[i]==1)
{
for(j=1;j<=n;j++)
sum[j]+=a[i][j];
}
}
for(i=1;i<=n;i++)
if(sum[i]<goal[i])
return false;
return true;
}
void dfs(int pp)
{
int i,j,t=0;
//printf("*");
if(pp==m+1)
{
//printf("*");
if(judge())
{
tot=0;
for(i=1;i<=m;i++)
if(vis[i]==1)
tot++;
if(tot>ans)
{
for(i=1;i<=m;i++)
if(vis[i]==1)
end[++t]=i;
ans=tot;
}
}
return;
}
vis[pp]=1;dfs(pp+1);
vis[pp]=0;dfs(pp+1);
}
int main()
{
int i,j;
while(scanf("%d",&n)!=EOF)
{
ans=0;
for(i=1;i<=n;i++)
scanf("%d",&goal[i]);
scanf("%d",&m);
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
scanf("%d",&a[i][j]);
memset(vis,0,sizeof(vis));
dfs(1);
printf("%d",ans);
if(ans>0)
{
for(i=1;i<=ans;i++)
printf(" %d",end[i]);
}
printf("\n");
}
return 0;
}
方法二:
因为范围比较小,可以用二进制来表示当前的状态,比如当现在有4行时,3就可以表示成0011,这就表示第一行和第二行都选了,而三四行没有选。(3>>i)&(1)是判断从右向左第(i+1)个值是什么。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m,a[26][30],goal[30],b[30],end[30],sum[30];
int cont,ans;
int f(int pp)
{
int i,t=1;
for(i=1;i<=m;i++)
t*=2;
return t-1;
}
bool judge()
{
int i;
memset(sum,0,sizeof(sum));
for(i=1;i<=m;i++)
{
if(b[i]==1)
{
for(int j=1;j<=n;j++)
sum[j]+=a[i][j];
cont++;
}
}
for(i=1;i<=n;i++)
{
if(sum[i]<goal[i])
return false;
}
return true;
}
int main()
{
int i,j;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%d",&goal[i]);
scanf("%d",&m);
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
scanf("%d",&a[i][j]);
}
int t=0;
ans=0;
//printf("%d\n",f(m));
for(i=1;i<=f(m);i++)
{
cont=0;
t=0;
memset(b,0,sizeof(b));
for(j=0;j<m;j++)
{
b[++t]=(i>>j)&(1);
}
if(judge())
{
if(cont>ans)
{
for(j=1;j<=m;j++)
{
end[j]=b[j];
}
ans=cont;
}
}
}
printf("%d",ans);
if(ans>0)
{
for(i=1;i<=m;i++)
if(end[i]==1)
printf(" %d",i);
}
printf("\n");
}
return 0;
}