emmm 记录一个自己犯傻的题目

链接:https://ac.nowcoder.com/acm/contest/303/D
来源:牛客网

题目描述

星际争霸(StarCraft)单人战役模式中有很多供人游玩的任务关卡。

 

tokitsukaze新开始了一关单人战役模式下的任务。在这场战役中,你要作为指挥官指挥克鲁普星区的艾伦人类(Terran)来防御人类的敌人——邪恶异虫(Zerg)的袭击。

 

这一次,作为指挥官,你的任务目标是尽可能多的保全人类方所拥有的7个基地。你在这次任务中拥有n个人口单位的兵力。为了防御异虫的攻击,每个基地都有一个能够抵挡异虫攻击的最小兵力需求L[i],同时每个基地因为有固定的人口上限,分配给该基地的兵力也不得大于上限R[i]。

 

你需要在任务一开始就为这7个基地做好兵力分配,每个兵都应该分配给一个基地,即不应该有空闲兵力。如果任何一个基地被异虫攻破(分配的兵力大于0,且小于最小兵力需求,导致兵力白白葬送牺牲),或者某个基地的人口超过了人口上限,兵力大于R[i],任务都会直接失败。

 

为了避免任务失败,tokitsukaze决定从一开始就放弃一些基地(即不对这些基地派出兵力)。

 

请问保证任务成功的条件下,tokitsukaze最多留下多少个基地?特别的,如果任务失败这种情况下请输出"0",不含引号。

 

由于tokitsukaze的星际操作十分流弊,你可以认为如果能够至少能够保留一个基地,任务就一定能够成功。

输入描述:

第一行输入一个T(T≤50000),表示T组数据。

对于每组数据:
输入一个正整数n(1≤n≤10^9)表示需要分配的兵力总人口。
接下来7行,每行两个正整数L,R(1≤L≤R≤10^9),分别表示该基地够抵挡异虫攻击的最小兵力需求与该基地的人口上限。

输出描述:

对于每组数据,输出tokitsukaze最多能够留下几个基地,每组数据占一行。

示例1

输入

4
50
1 1
1 1
1 1
1 1
1 1
1 1
1 1
50
1 1
20 30
20 30
20 30
1 1
20 30
20 30
70
19 19
10 10
10 10
10 10
10 10
10 10
1 1
2
1 1
3 3
3 3
3 3
3 3
3 3
3 3

输出

0
4
7
0
#include <bits/stdc++.h>

using namespace std;
struct sta
{
    long long int r,l;
} s[10];

int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        int max=0;
        long long mr,ml,sum;
        scanf("%lld",&sum);
        for(int i=0; i<7; i++)
            scanf("%lld %lld",&s[i].l,&s[i].r);
        /**
             七个  可选可不选 并不算 7!
             而是2^7  1111111 共有128种 按位计算
        */
        for(int i=0;i<128;i++)
        {
            int j=0,select = i,con = 0;
            mr=0,ml=0;
            while(select)
            {
                if(select&1)
                {
                    mr = mr + s[j].r;
                    ml = ml + s[j].l;
                    con++;
                }
                if(ml>sum)
                {
                    con=0;
                    break;
                }
                select = select >> 1;
                j++;
            }
            if(mr<sum)
                con=0;
            if(con>max)
                max = con;
        }
        printf("%d\n",max);
    }
}

当然 这题也可以用 dfs 过 。

附上 我同学过的  emmm  个人没想写dfs了 0.0  

#include <bits/stdc++.h>
using namespace std;
long long sum1,sum2,n,ans;
struct fun
{
    long long int a,b;
};
fun a[10];
int p[10];
void dfs(long long s,long long suma,long long sumb,long long j)
{
    if(suma<=sumb)
        ans=max(ans,s);
    //printf("%lld%lld%lld\n",s,suma,sumb);
    if(suma==0)
        return ;
    for(int i=j;i<=7;i++)
    {
        if(p[i]==1)
        {
            if(suma>=a[i].a)
            {
                p[i]=0;
                dfs(s+1,suma-a[i].a,sumb+a[i].b-a[i].a,i+1);
                p[i]=1;
            }
        }
    }
}
int main()
{
    int t;
 
    scanf("%d",&t);
    while(t--)
    {
        sum1=0,sum2=0,ans=0;
        scanf("%lld",&n);
        for(int i=1;i<=7;i++)
        {
            p[i]=1;
            scanf("%lld%lld",&a[i].a,&a[i].b);
            sum1=min(sum1,a[i].a);
            sum2=sum2+a[i].b;
        }
        if(sum2<n||sum1>n)
            printf("0\n");
        else
        {
            dfs(0,n,0,1);
            dfs(0,n,0,2);
            dfs(0,n,0,3);
            dfs(0,n,0,4);
            dfs(0,n,0,5);
            dfs(0,n,0,6);
            dfs(0,n,0,7);
            printf("%lld\n",ans);
        }
    }
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值