【HDU】 3605 Escape(暴力做法...)

6 篇文章 0 订阅
4 篇文章 0 订阅

Escape


题目链接


题目大意

意思就是说现在世界末日要来了,地球上有n各人要跑到其他的星球上去,但是每个人只

能到若干星球上去,现在告诉你每个星球能容纳的人数,需要你判断是否所有的人都能

躲过世界末日。


题解

这道题首先看到人数很多,但是星球只有10个,所以我们考虑不同的人最多只有

2101 个,这样我们就可以用位元算的方式解出每种人有多少个,然后开始建图。

  • 建图

总共m+1个点,源点是m,汇点是m+1,我们遍历每一种人,从源点向他能去的点建立

一条长度为该种人人数的边,再从每一个星球向汇点建立一条长度为该星球能容纳人数

的边。

  • 处理

我们发现建完这个图后,对于每个星球,有且仅有两条边与他相连,一个是从源点过来

的,一条是指向汇点的,所以我们现在只需要将这两条边取最小的然后加到 ans 中就行

了(暴力)…


代码

最后取最大的时候是很快的,主要时间都在建图了(交了10次,平均时间在1700ms左右,有一次超时)…

能暴力为啥不暴力啊!!!

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>

using namespace std;

int n,m,x,nump[1050],p[15],e[30];
int c[11]={1,2,4,8,16,32,64,128,256,512,1024};

int solve()
{
   int ans=0;
   for (int i=0;i<m;i++) ans+=min(e[i],e[i+m]);
    return ans;
}

int main()
{
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        memset(p,0,sizeof(p));
        memset(nump,0,sizeof(nump));
        for (int i=1;i<=n;i++)
        {
            int sum=0;
            for (int j=1;j<=m;j++)
            {
                scanf("%d",&x);
                if (x) sum+=c[j-1];
            }
            nump[sum]++;
        }
        for (int i=0;i<m;i++) scanf("%d",&p[i]);
        if (nump[0])
        {
            printf("NO\n");
            continue;
        }
        //deal
        memset(e,0,sizeof(e));
        for (int i=1;i<=c[m];i++) if (nump[i])
            for (int j=0;j<m;j++) if ((1<<j)&i) e[j]+=nump[i];
        for (int i=0;i<m;i++) if (p[i]) e[i+m]+=p[i];
        int ans=solve();
        if (ans>=n) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值