E. Cheap Dinner

链接戳这
题意:
给定n1,n2,n3,n4种菜肴和m1,m2,m3之间的关系来说明两者不能共存,求最小的花费。
思路:
这题需要数据结构来优化,由于这题符合动态规划的性质,例如abcd数组,a对b数组的影响对c是不具有后效性的,所以我们可以先从a出发递推到d,然后如果暴力咋做呢,也就是对于图片说明 ,那复杂度是图片说明 ,如何优化呢。我们把每条不符合的边插入到每个b的set中,然后对于a按照val来排序,枚举每个b,然后从小到大枚举a,如果b的set中不存在就可以提前break,这不仔细看复杂度比之前还高啊,图片说明 但是由于不符合题目要求的边的个数是图片说明 ,也就是第二层循环总共加起来不会超过m,那么复杂度就是图片说明
代码:

#include<bits/stdc++.h>
using namespace std;
const int N=200010;
const int INF=0x3f3f3f3f;
int n1,n2,n3,n4;
int m1,m2,m3;
set<int>s1[N],s2[N],s3[N];
struct node{
    int val;
    int id;
    bool operator<(const node&W)const
    {
        return val<W.val;
    }
}a[N],b[N],c[N],d[N];
void solve(node a[],node b[],int n1,int n2,set<int>s[])
{
    sort(a+1,a+1+n1);
    for(int i=1;i<=n2;i++)
    {
        bool flag=0;
        for(int j=1;j<=n1;j++)
        {
            if(s[i].find(a[j].id)==s[i].end())
            {
                flag=1;
                b[i].val=b[i].val+a[j].val;
                break;
            }

        }
            if(!flag)
                b[i].val=INF;
    }
}
int main()
{
    ios::sync_with_stdio(0);
    cin>>n1>>n2>>n3>>n4;
    for(int i=1;i<=n1;i++)    cin>>a[i].val,a[i].id=i;
    for(int i=1;i<=n2;i++)    cin>>b[i].val,b[i].id=i;
    for(int i=1;i<=n3;i++)    cin>>c[i].val,c[i].id=i;
    for(int i=1;i<=n4;i++)    cin>>d[i].val,d[i].id=i;
    cin>>m1;
    for(int i=0;i<m1;i++)
    {
        int x,y;    cin>>x>>y;
        s1[y].insert(x);
    }
    cin>>m2;
    for(int i=0;i<m2;i++)
    {
        int x,y;     cin>>x>>y;
        s2[y].insert(x);
    }
    cin>>m3;
    for(int i=0;i<m3;i++)
    {
        int x,y; cin>>x>>y;
        s3[y].insert(x);
    }
    solve(a,b,n1,n2,s1);
    solve(b,c,n2,n3,s2);
    solve(c,d,n3,n4,s3);
    int res=INF;
    for(int i=1;i<=n4;i++)
        res=min(res,d[i].val);


    if(res==INF)    res=-1;

    cout<<res<<"\n";

    return 0;
}
全部评论

相关推荐

11-21 09:17
门头沟学院 Java
投递多益网络等公司6个岗位
点赞 评论 收藏
分享
12-24 20:44
武汉大学 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务