1 条题解

  • 0
    @ 2025-8-24 22:01:08

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Unknown_Error 
    OI(2014-2018)

    搬运于2025-08-24 22:01:08,当前版本为作者最后更新于2018-05-06 21:45:28,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    我们可以把每个任务所有满足条件的分人方式记录下来。由于人数很少可以用位运算。

    按起始时间排序,由于只是改变了原序列对任务分配时的编号,所以用myp标记一下即可。

    其实。。。这完全可以暴力

    暴力判断是否可行。

    真暴力

    代码附上:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <vector>
    using namespace std;
    #define pb(a) push_back(a)
    int n,m;
    int task[20][20];
    struct node
    {
        int need,val,st,ed,id;
    }save[100];
    long long ans;
    long long kind[20][2048];
    int tim[100],myp[100],sum[100];
    void dfs(int now,int val)
    {
        if(val>ans)
        {
            ans=val;
        }
        if(now>m) return ;
        dfs(now+1,val);
        bool flag;
        int tmp[20];
        for(int j=1;j<=n;j++) tmp[j]=tim[j];
        for(int i=1;i<=kind[myp[now]][0];i++)
        {
            flag=true;
            for(int j=1;j<=n;j++)
            {
                if( (kind[myp[now]][i]>>(j-1))&1)
                {
                    if(tim[j]<save[now].st)
                    {
                        tim[j]=save[now].ed;
                    }
                    else
                    {
                        flag=false;
                        break;
                    }
                }
            }
            if(flag)
            {
                dfs(now+1,val+save[now].val);
            }
            for(int j=1;j<=n;j++) tim[j]=tmp[j];
        }
    }
    bool cmp(node aa,node bb)
    {
        return aa.st<bb.st;
    }
    
    bool judge(int num)
    {
        if(sum[num]==save[num].need) return true;
        return false;
    }
    int main()
    {
        
        int a,b,c;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a);
            for(int j=1;j<=a;j++)
            {
                scanf("%d",&b);
                task[i][b]=1;
            }
        }
        for(int i=1;i<=m;i++)
        {
           scanf("%d%d%d%d",&save[i].st,&save[i].ed,&save[i].need,&save[i].val);
           save[i].id=i;
        }
    
        int k;
        for(int i=1;i<=(1<<n)-1;i++)
        {
            k=0;
            for(int j=1;j<=m;j++)
                sum[j]=0;
            for(int j=1;j<=n;j++)
            {
                if( (i>>(j-1))&1 )
                {
                    k++;
                    for(int t=1;t<=m;t++)
                    {
                        if(task[j][t])
                        {
                            sum[t]++;
                        }
                    }
                }
            }
            for(int j=1;j<=m;j++)
            {
                if(judge(j))
                {
                    if(sum[j]!=k) continue;
                    kind[j][0]++;
                    kind[j][kind[j][0]]=i;
                }
            }
        }
        sort(save+1,save+1+m,cmp);
        for(int i=1;i<=m;i++)
        {
            myp[i]=save[i].id;
            //printf("%d\n",myp[i]);
        }
        dfs(1,0);
        printf("%lld\n",ans);
        return 0;
    
    
    • 1

    信息

    ID
    3516
    时间
    1000ms
    内存
    128MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者