hdu4152 二进制枚举

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4152


/*
4
100 200 300 400
3
100 100 400 500
100 -10 50 300
100 100 -50 -50
*/
#include

int goal[30];
int f[25][25],g[30];

main(){
  int i,j,n,m,ans1,ans2;
  while(scanf("%d",&n)!=EOF){
    ans1=-1;
    for(i=0;i<n;i++)
      scanf("%d",&goal[i]);
    scanf("%d",&m);
    for(i=0;i<m;i++)
      for(j=0;j<n;j++)
        scanf("%d",&f[i][j]);
    for(i=0;i<(1<<m);i++){
      for(j=0;j<n;j++)
        g[j]=0;
      int num=0,k;
      for(j=0;j<m;j++)
        if(i&(1<<j)){
          num++;
          for(k=0;k<n;k++)
            g[k]+=f[j][k];
        }
      int p;
      for(p=0;p<n;p++)
        if(g[p]=n){
        if(num>ans1)ans1=num,ans2=i;
        else if(num==ans1&&ans2>i)
          ans1=num,ans2=i;
      }
    }
    if(ans1==-1)printf("0\n");
    else{
      printf("%d",ans1);
      for(i=0;i<n;i++)
        if(ans2&(1<<i))
          printf(" %d",i+1);
      printf("\n");
    }
  }

}


 这段代码可以清楚地理解二进制枚举究竟是怎样的

#include<stdio.h>  
int goal[30];
int f[25][25],g[30];
main(){
  int n,i,j,k,m,ans1,ans2;
    scanf("%d",&m);
    for(i=1;i<(1<<m);i++){
      printf("%d ",i);
      int num=0;
      for(j=0;j<m;j++){    
      if(i&(1<<j)){//i==2^j
          printf("%d ",j);
      else
          printf("* ");
      printf("\n");
    }
}

计蒜客的题目(换成最少习惯,没说全吃掉也不满足的情况,所以不知道第六组测试点怎么过)

题目地址:https://nanti.jisuanke.com/t/41

#include

int goal[40];
int f[40][40],g[40];

main(){
  int i,j,n,m,ans1,ans2;
 // while(scanf("%d",&n)!=EOF){
    scanf("%d",&n);
    ans1=99999999;
    for(i=0;i<n;i++)
      scanf("%d",&goal[i]);
    scanf("%d",&m);
    for(i=0;i<m;i++)
      for(j=0;j<n;j++)
        scanf("%d",&f[i][j]);
    for(i=1;i<(1<<m);i++){
      for(j=0;j<n;j++)
        g[j]=0;
      int num=0,k;
      for(j=0;j<m;j++)
        if(i&(1<<j)){
          num++;
          for(k=0;k<n;k++)
            g[k]+=f[j][k];
        }
      int p;
      for(p=0;p<n;p++)
        if(g[p]=n){                    //不是废话,说明前面遍历过了,达到目标了
      if(num<ans1)ans1=num,ans2=i;//改成<,就是找最小的,而且i从1开始,j那层循环不会有和它匹配不上的,也就是说,一定会有num++
      else if(num==ans1&&ans2>i)  //习惯数相同,输出靠前的
        ans2=i;
    }
    }
    if(ans1==99999999){
      printf("%d",n);
      for(i=0;i<n;i++)
        printf(" %d",i+1);
    }
    else{
      printf("%d",ans1);
      for(i=0;i<n;i++)
        if(ans2&(1<<i))
          printf(" %d",i+1);
      printf("\n");
    }
  //}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值