• NOIP模拟---movie


    题头

    【描述】
    小石头喜欢看电影,选择有 N 部电影可供选择,每一部电影会在一天的不同时段播
    放。他希望连续看 L 分钟的电影。因为电影院是他家开的,所以他可以在一部电影播放过
    程中任何时间进入或退出,当然他不希望重复看一部电影,所以每部电影他最多看一次,
    也不能在看一部电影的时候,换到另一个正在播放一样电影的放映厅。
    请你帮助小石头让他重 0 到 L 连续不断的看电影,如果可以的话,计算出最少看几
    部电影。
    【输入格式】
    第一行是 2 个整数 N,L,表示电影的数量,和小石头希望看的连续时间
    接下来是 N 行,每行第一个整数 D(1<=D<=L)表示电影播放一次的播放时间,第二个整数
    是 C 表示这部电影有 C 次播放,接下来是 C 个整数表示 C 次播放的开始时间 Ti
    (0<=Ti<=L),Ti 是按升序给出。
    【输出格式】
    一个整数,表示小石头最少看的电影数量,如果不能完成输出-1
    【输入样例】
    4 100
    50 3 15 30 55
    40 2 0 65
    30 2 20 90
    20 1 0
    【输出样例】
    3
    【样例说明】
    开始他选择最后一步电影从 0 时间开始。
    到了 20 分钟,他选择第一部电影的第一次播放,看到 65 分钟
    最后他选择第二部电影的第二次播放,从 65 分钟到 100 分钟
    【数据规模】
    30%数据 N<=10
    100%数据 N<=20, 1 <= L <= 100,000,000 ,C<=1000

    还算简单吧,但好像暴力很不好写;

    一看N的范围就是个状压dp了,而且是贪心,让当前电影最晚结束,然后乱搞一通差不多就出来了

    我旁边的大佬%%%%%用随机化贪心过了90分%%%%%

    #include<bits/stdc++.h>
    using namespace std;
    #define inf 0x3f3f3f3f
    inline int read(){
        char ch;
        while((ch=getchar())<'0'||ch>'9'){; }
        int res=ch-'0';
        while((ch=getchar())>='0'&&ch<='9')
        res=res*10+ch-'0';
        return res;
    }
    int n,m,tim[25],num[25],c[22][1005],s,ans,f[1<<21];
    inline int find(int x,int id)
    {
        int l=-1,r=num[id]-1,mid,ans;
        while(l<r)    {
            int mid=l+r+1>>1;
            if(c[id][mid]<=x)l=mid;
            else r=mid-1;
        }
        return l;
    }
    int main(){
        n=read(),m=read();
        for(int i=0;i<n;i++)
        {
            tim[i]=read();
            num[i]=read();
            for(int j=0;j<num[i];j++)
            {
                c[i][j]=read();
            }
        }
        ans=inf;
        s=1<<n;
        memset(f,-1,sizeof(f)); f[0]=0;
        for(int i=0;i<s;i++)
        {
            if(f[i]==-1) continue;
            if(f[i]>=m)
            {
                int j=0;
                for(int k=i;k;k-=(k&-k))j++;
                ans=min(ans,j);
                continue;
            }
            for(int j=0;j<n;j++)
            {
                if(i&(1<<j)) continue;
                int k=find(f[i],j);
                if(k==-1) continue;
                f[i|(1<<j)]=max(f[i|(1<<j)],c[j][k]+tim[j]);
            }
        }
        if(ans==inf) cout<<-1<<endl;
        else cout<<ans<<endl;
    }
  • 相关阅读:
    Window 窗口类
    使用 Bolt 实现 GridView 表格控件
    lua的table库
    Windows编程总结之 DLL
    lua 打印 table 拷贝table
    使用 xlue 实现简单 listbox 控件
    使用 xlue 实现 tips
    extern “C”
    COleVariant如何转换为int double string cstring
    原来WIN32 API也有GetOpenFileName函数
  • 原文地址:https://www.cnblogs.com/forever-/p/9736084.html
Copyright © 2020-2023  润新知