zoukankan      html  css  js  c++  java
  • HNOI2018

    Day1

    Day2

    游戏

    https://www.luogu.org/problemnew/show/P4436

    前二十分暴力

    对于 y <= x 的数据,只要门被上锁,便无法从右向左,从1~n扫一遍很容易得到每个点能遍历的区间的左端点

    因为所有钥匙都在门左侧,那么从1一定能走到n,初始 l=1, r=n

    再依次枚举起点s,若无法向左走到l,则需要l ~ i - 1这段路上的钥匙的门也无法通过,更新r

    考虑到若 rmin< s ,则当前 r 对 s 对应的区间已无限制, r 应取大于 s 的最小值这里我是用堆维护

    剩下40分,坑先挖着吧,以后来填

    20 + 40 分代码
    #include <bits/stdc++.h>
    using namespace std;
    #define N 1000005
    
    int n, m, Q;
    int key[N], ans[N][2];
    vector<int> sum[N];
    priority_queue<int, vector<int>, greater<int> > q;
    
    inline int read()
    {
        int x = 0, f = 1; char ch = getchar();
        while(ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
        while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
        return x * f;
    }
    
    int main()
    {
        n = read(); m = read(); Q = read();
        bool casexy = true;
        for (int i = 1; i <= m; i++)
        {
            int x = read(), y = read();
            key[x] = y;
            if (x != y) sum[y].push_back(x);
            if (x < y) casexy = false;
        }
        if (casexy)
        {
            int p = 1;
            for (int i = 1; i <= n; i++)//先处理出左端点
            {
                ans[i][0] = p;
                if (key[i]) p = i + 1;
            }
            int l = 1, r = n; q.push(n);
            for (int i = 1; i <= n; i++)
            {
                while(r < l && !q.empty())
                {
                    q.pop(); r = q.top();
                }
                if(r < i) {ans[i][1] = i; continue;}
                ans[i][1] = r;
                while (ans[i + 1][0] > l)
                {
                    for(int j = 0; j < sum[l].size(); j++)
                    {
                        r = min(r, sum[l][j]);
                        q.push(sum[l][j]);
                    }
                    l++;
                }
            }
            while (Q--)
            {
                int x = read(), y = read();
                if (ans[x][0] <= y && ans[x][1] >= y) puts("YES"); else puts("NO");
            }
        }
        else
        {
            for(int i = 1; i <= n; i++) ans[i][0] = ans[i][1] = i;
            for(int s = 1; s <= n; s++)
            {
            	 int l = s, r = s;
            	 while(l > 1 || r < n)
            	 {
            	 	if(l > 1 && (!key[l - 1] || (key[l - 1] >= l && key[l - 1] <= r))) l = ans[l - 1][0];
            	 	else if(r < n && (!key[r] || (key[r] >= l && key[r] <= r))) r = ans[r + 1][1];
            	 	else break;
            	 }
            	 ans[s][0] = l; ans[s][1] = r;
            }
            while(Q--)
            {
            	int x = read(), y = read();
            	if (ans[x][0] <= y && ans[x][1] >= y) puts("YES"); else puts("NO");
            }
        }
        return 0;
    }
    

    道路

    https://www.luogu.org/problemnew/show/P4438

    考场上觉得暴搜打那么多只有20分太不划算,然而同行julao说暴搜有70

    喵喵喵???

    然后更加ju的julao传授了dp 40行AC代码

    我果然还是太菜了啊

    #include <bits/stdc++.h>
    using namespace std;
    #define N 20005
    #define M 45
    #define inf 1000000000000000
    #define ll long long
    
    int n;
    int s[N], t[N];
    int a[N], b[N], c[N];
    
    ll f[M][M];//f[i][j]表示从当前节点向上有i条公路,j条铁路待修
    void dfs(int x, ll T[M][M])
    {
        if(x < 0)//所有乡村均为叶子节点
        {
            x *= -1;//节点暴力枚举所有情况
            for(int i = 0; i <= 40; i++)
                for(int j = 0; j <= 40; j++)
                    T[i][j] = (ll)c[x] * (a[x] + i) * (b[x] + j);
            return;
        }
        ll l[M][M], r[M][M];
        dfs(s[x], l); dfs(t[x], r);
        for(int i = 0; i <= 40; i++)//f[x][i][j] 省去一维
            for(int j = 0; j <= 40; j++)
                T[i][j] = min(l[i][j] + r[i][j + 1], l[i + 1][j] + r[i][j]); //选择公路或铁路进行翻修
    }
    
    int main()
    {
        scanf("%d", &n);
        for(int i = 1; i < n; i++) scanf("%d%d", &s[i], &t[i]);//二叉树
        for(int i = 1; i <= n; i++) scanf("%d%d%d", &a[i], &b[i], &c[i]);
        dfs(1, f);
        printf("%lld", f[0][0]);
        return 0;
    }
  • 相关阅读:
    swift语言点评十三-Lazy
    swift语言点评十二-Subscripts
    swift语言点评十一-Methods
    命题和判断有什么区别和联系
    形式逻辑三大基本要素-推理的本质
    逻辑的本质是结构和联系的可推理性
    swift语言点评十-Value and Reference Types
    swift语言点评九-类与结构
    swift语言点评八-枚举
    阅读与带宽
  • 原文地址:https://www.cnblogs.com/XYZinc/p/8854765.html
Copyright © 2011-2022 走看看