• P6775 [NOI2020] 制作菜品


    P6775 [NOI2020] 制作菜品

    链接

    P6775 [NOI2020] 制作菜品

    题解

    分三种情况讨论:
    1.m=n-1,就是alias method。。(NOI考的算法越来越怪啦QAQ),这里是(O(n))的。
    2.m>=n,这个时候一定存在某些材料不小于K克,强行用这个材料减K,这样m减少1,n可能不变可能减1。不断重复就能做完或者变成1情况。(O(n))
    3.m=n-2,有解的情况当且仅当可以分成两个1情况。可以(O(n^2k))DP,用bitset优化就能通过这题了。

    (Code)

    #include<bits/stdc++.h>
    using namespace std;
    const int N=5005;
    const int M=5005*505;
    int n,m,K;
    struct Node{
        int id;
        int V;
    }a[N];
    int v[N];
    int cnt;
    struct ANS{
        int idx,Vx;
        int idy,Vy;
    }b[N];
    vector<Node> c,d;
    void sol(vector<Node> A){
        c.clear();d.clear();
        for(int i=0;i<A.size();++i){
            if(A[i].V>=K) d.push_back(A[i]);
            else c.push_back(A[i]);
        }
        int i=0,j=0;Node tmp;
        while(i<c.size()){
            tmp=c[i];++i;
            ++cnt;b[cnt].idx=tmp.id;b[cnt].Vx=tmp.V;
            if(j<d.size()){
                b[cnt].idy=d[j].id;b[cnt].Vy=K-tmp.V;
                d[j].V-=b[cnt].Vy;
                if(d[j].V<K){
                    c.push_back(d[j]);
                    ++j;
                }
            }
            else{
                b[cnt].idy=c[i].id;b[cnt].Vy=K-tmp.V;
                c[i].V-=b[cnt].Vy;
                if(c[i].V==0) ++i;
            }
        }
        return;
    }
    
    bitset<M+M+1> f[505];
    vector<Node> q1,q2;
    void MAIN(){
        scanf("%d%d%d",&n,&m,&K);
        for(int i=1;i<=n;++i) {
            a[i].id=i;
            scanf("%d",&a[i].V);
        }
        cnt=0;
        for(int i=1;i<=m;++i){
            b[i].idx=b[i].Vx=b[i].idy=b[i].Vy=0;
        }
        int l=1;
        while(n<=m&&m>0){
            while(a[l].V<K)++l;
            ++cnt;
            b[cnt].idx=a[l].id;
            b[cnt].Vx=K;
            m--;
            a[l].V-=K;
            if(a[l].V==0){
                swap(a[l],a[n]);
                --n;
            }
        }
        if(m>0){
            if(m==n-2){
                for(int i=1;i<=n;++i) v[i]=a[i].V-K;
                f[0].reset();
                f[0].set(M);
                for(int i=1;i<=n;++i){
                    f[i]=f[i-1];
                    if(v[i]>=0) f[i]|=f[i-1]<<v[i];
                    else f[i]|=f[i-1]>>(-v[i]);
                }
                if(!f[n][M-K]){
                    puts("-1");
                    return;
                }
                q1.clear();q2.clear();
                int now=M-K;
                for(int i=n;i>=1;--i){
                    if(f[i-1][now-v[i]]){
                        q1.push_back(a[i]);
                        now=now-v[i];
                    }
                    else{
                        q2.push_back(a[i]);
                    }
                }
                sol(q1);sol(q2);
            }
            else if(m==n-1){
                q1.clear();
                for(int i=1;i<=n;++i) q1.push_back(a[i]);
                sol(q1);
            }
        }
        for(int i=1;i<=cnt;++i){
            printf("%d %d",b[i].idx,b[i].Vx);
            if(b[i].idy) printf(" %d %d",b[i].idy,b[i].Vy);
            puts("");
        }
        return;
    }
    int main(){
        int ttt=1;scanf("%d",&ttt);
        while(ttt--) MAIN();
        return 0;
    }
    
  • 相关阅读:
    Nginx 教程(安装在Windows)
    APS.Net Core 启用跨域请求
    C# 监听数据库表的变化(SqlDependency)
    C# WebSocket 及时通信协议
    Sqlserve 常用语句
    C# Socke t网络编程
    什么是分布式缓存
    好诗!!!
    ASP.NET MVC中获取URL地址参数的两种写法
    jQueryEasyUI Messager基本使用
  • 原文地址:https://www.cnblogs.com/Yuigahama/p/14673544.html
Copyright © 2020-2023  润新知