炫酷雪花

【题目描述】

小希在家里做着作业,外面飘起了斗大的雪花,很冷!

小希把接下来连续的要做作业的时间分成n个单位,每个单位时间内小希都会受到ai的寒冷值侵袭,她可以选择在任何一些时间站起来蹦蹦跳跳,以使得这个单位的寒冷值不侵袭她。

小希最大能承受的寒冷程度是K,但是她想选择尽可能多的时间做作业,请你帮帮她!

小希受到的寒冷程度即为不蹦蹦跳跳的时间的寒冷值总和。

【输入描述】

第一行两个整数n,k表示时间总长为n个单位,小希最大能承受的寒冷程度是K。

随后一行n个整数,第i个整数表示第i个时间单位小希会受到ai的寒冷值。

1≤n≤5,000
0≤K≤1,000,000,000,000,000
0≤ai≤1,000,000,000

【输出描述】

第一行输出一个整数ans表示小希最多的学习时间。

第二行输出一个字符串,表示一个可行的方案,长度为n,第i个字符为1表示这个单位时间站起来蹦蹦跳跳,为0表示这个单位时间好好学习。

如果有多种可行方案,请输出字典序最小的。

【样例】

示例1

输入
3 5
1 2 3
输出
2
001

示例1

输入
5 9
3 3 3 3 3
输出
3
00011

思路:

蹦蹦跳跳的次数可以通过贪心来选取尽可能冷的时间进行蹦蹦跳跳来取得的,由于最后要输出字典序最小的方案,因此可设置一个标记数组,存储是否进行了蹦蹦跳跳,并将蹦蹦跳跳的时间放入栈中,最后根据标记数组进行出栈即可

要注意 k 的范围需要开 long long

【源代码】

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define PI acos(-1.0)
#define E 1e-6
#define INF 0x3f3f3f3f
#define N 1000001
#define LL long long
const int MOD=998244353;
const int dx[]={-1,1,0,0};
const int dy[]={0,0,-1,1};
using namespace std;
#include<iostream>
using namespace std;
int a[N];
int bucket[N];
bool flag[N];
bool cmp(int x,int y){
    return a[x]<a[y];
}
int main(){
    int n;
    LL k;
    scanf("%d %lld",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);//寒冷时间
        bucket[i]=i;//寒冷时间序号
        flag[i]=true;//标记
    }
    sort(bucket+1,bucket+1+n,cmp);


    LL sum=0;//最多寒冷时间
    int res=0;//最多学习时间
    stack <int> S;
    for(int i=1;i<=n;i++){
        if(sum+a[bucket[i]]>k)//承受值
            break;
        else {
            res++;
            sum+=a[bucket[i]];
            flag[bucket[i]]=false;

            S.push(bucket[i]);//对蹦蹦跳跳的时间入栈
        }
    }
    printf("%d\n",res);


    for(int i=1;i<=n;i++){
        if(flag[i]){
            while(!S.empty()){
                int temp=S.top();
                if(sum-a[temp]+a[i]>k)
                    break;

                S.pop();

                if(temp<i)
                    continue;

                flag[i]=false;
                flag[temp]=true;
                sum=sum-a[temp]+a[i];
                break;
            }
        }
        printf("%d",flag[i]);

    }
    printf("\n");
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值