zoukankan      html  css  js  c++  java
  • NOIP模拟1717 总结

    总结

    T1: 有x个人在a时b分来,c时d分离开,求所有时刻中人数的最大值。
    差分裸题,当然也可以写线段树。

    第一题一般来说思维都不会太复杂,如果打的时间很长,便要调整自己的思路,要保证A掉。

    T2: 对一个数组进行新定义的排序:选出数组中的不和谐数(严格小于左边第一个数(左边有数)或严格大于右边第一个数(右边有数)),将其一起删掉,重复操作直到不存在不和谐数。
    双向链表的运用:先在第一遍中将需要删除的数加入删除列表,然后循环处理删除列表至其为空:将每一段的左右两边的第一个加入检查列表(删除过后会改变相邻关系,但每删除一段连续的下降序列只会影响其左右两端)只加入左右两边,保证复杂度,将删除列表清空,然后再来遍历检查列表,将检查列表中的不符合的加入删除列表,一遍下一次遍历。

    此题爆0,因为我以为自己写的是正解,于是不屑于打对拍(!!!亏啊)——越是简单的题,越要保证正确。

    T3: 只有两个颜色的祖玛游戏(连续的三个可以消除,可以向任意位置插入一个)。求最小消除次数。
    读题就觉得和bzoj的一道错题很像。。消除类型的多半就是区间dp,但此题的转移情况有4种,要不重不漏的转移完全才能A掉。

    1. 将原序列进行压缩,相同的一段用一个点表示,并记录其包含的个数sze。
    2. 分类写出方程 :

    [dp[l][r] = min(dp[l][r], 3 - sze[l]) (l == r) ]

    [dp[l][r] = min(dp[l][r], dp[l][k], dp[k + 1][r] (l le k < r) ]

    [dp[l][r] = min(dp[l][r], do[l + 1][k - 1] + dp[k + 1][r - 1]) (col[l] == col[r] && sze[l] + sze[r] != 4 && sze[k] == 1, (l < k < r)) ]

    [dp[l][r] = min(dp[l][r], do[l + 1][r - 1] + max(0, 3 - sze[l] - sze[r])) ]

    时间复杂度(O(n^3))

    本题情况考虑完了,但是转移的不够干净利落,考试只得了60分。刚刚复习完区间dp,做的题还没有达到这种难度,dp题要多刷,多总结其中的奥妙。

    code

    T1

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    namespace IO{
        inline int read(){
            int i = 0, f = 1; char ch = getchar();
            for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
            if(ch == '-') f = -1, ch = getchar();
            for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch - '0');
            return i * f;
        }
        inline void wr(long long x){
            if(x < 0) putchar('-'), x = -x;
            if(x > 9) wr(x / 10);
            putchar(x % 10 + '0');
        }
    }using namespace IO;
    const int N = 1e5 + 5, M = 2000, OO = 0x3f3f3f3f;
    typedef long long ll;
    ll sum[M], ans;
    int n, maxx, minn;
    int main(){
    	n = read(); minn = OO, maxx = 0;
    	for(int i = 1 ; i <= n; i++){
    		int x = read(), a = read(), b = read(), c = read(), d = read();
    		sum[a * 60 + b] += x;
    		sum[c * 60 + d] -= x; 
    		minn = min(minn, a * 60 + b);
    		maxx = max(maxx, c * 60 + d);
    	}
    	for(int i = minn; i <= maxx; i++) sum[i] = sum[i - 1] + sum[i], ans = max(ans, sum[i]);
    	wr(ans), putchar('
    ');
    	return 0;
    }
    

    T2

    #include<bits/stdc++.h>
    using namespace std;
    
    namespace IO{
        inline int read(){
            int i = 0, f = 1; char ch = getchar();
            for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
            if(ch == '-') f = -1, ch = getchar();
            for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch - '0');
            return i * f;
        }
        inline void wr(int x){
            if(x < 0) putchar('-'), x = -x;
            if(x > 9) wr(x / 10);
            putchar(x % 10 + '0');
        }
    }using namespace IO;
    
    const int N = 1E6 + 5;
    int n, T, head;
    struct node{int last, nxt, val;}bdList[N]; 
    vector<int> delList, chckList, ans;
    bool del[N], chck[N];
    
    inline bool gg(int k){
        int last = bdList[k].last, nxt = bdList[k].nxt;
        if(last > 0 && bdList[last].val > bdList[k].val) return true;
        if(nxt < n + 1 && bdList[nxt].val < bdList[k].val) return true;
        return false;
    }
    
    inline void dele(int k){
        int last = bdList[k].last, nxt = bdList[k].nxt;
        if(head == k) head = nxt;  
        if(last > 0) bdList[last].nxt = nxt;
        if(nxt < n + 1) bdList[nxt].last = last;
    }
    
    int main() {
        T = read();
        while(T--){
            n = read();
            delList.clear(), chckList.clear(), memset(bdList, 0, sizeof bdList), memset(del, 0, sizeof del), memset(chck, 0, sizeof chck);
            for(int i = 1; i <= n; i++) 
                bdList[i].last = i - 1, bdList[i].nxt = i + 1, bdList[i].val = read();
            head = 1;
            for(int i = 1; i <= n; i++)
                if(gg(i)) delList.push_back(i), del[i] = true;
            while(delList.size()){
                for(int i = delList.size() - 1; i >= 0; i--) {
                    int last = bdList[delList[i]].last, nxt = bdList[delList[i]].nxt;
                    if(last > 0 && !del[last] && !chck[last]) chckList.push_back(last), chck[last] = true;
                    if(nxt < n + 1 && !del[nxt] && !chck[nxt]) chckList.push_back(nxt), chck[nxt] = true;
                    dele(delList[i]);
                }
                delList.clear();
                for(int i = chckList.size() - 1; i >= 0; i--){
                    chck[chckList[i]] = false;
                    if(gg(chckList[i])) delList.push_back(chckList[i]), del[chckList[i]] = true;
                }
                chckList.clear();
            }
            ans.clear();
            for(; head <= n; head = bdList[head].nxt) ans.push_back(bdList[head].val);
            cout<<ans.size()<<endl;
            for(int i = 0; i < ans.size(); i++) cout<<ans[i]<<" ";cout<<endl;
        }
        return 0;
    }
    

    T3

    #include<bits/stdc++.h>
    using namespace std;
    
    namespace IO{
        inline int read(){
            int i = 0, f = 1; char ch = getchar();
            for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
            if(ch == '-') f = -1, ch = getchar();
            for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch - '0');
            return i * f;
        }
        inline void wr(int x){
            if(x < 0) putchar('-'), x = -x;
            if(x > 9) wr(x / 10);
            putchar(x % 10 + '0');
        }
    }using namespace IO;
    
    const int N = 205, OO = 0x3f3f3f3f;
    int n, T, head;
    int dp[N][N], sze[N];
    char M[N], S[N];
    
    inline int DP(int l, int r){
        if(dp[l][r] != -1) return dp[l][r];
        if(l == r) return dp[l][r] = 3 - sze[l];
        dp[l][r] = OO;
        if(S[l] == S[r]){
            dp[l][r] = min(dp[l][r], DP(l + 1, r - 1) + max(0, 3 - sze[l] - sze[r]));
            if(sze[l] + sze[r] != 4)
                for(int k = l + 1; k <= r - 1; k++) 
                	if(sze[k] == 1 && S[k] == S[l]) dp[l][r] = min(dp[l][r], DP(l + 1, k - 1) + DP(k + 1, r - 1));
        }
        for(int k = l; k < r; k++)
            dp[l][r] = min(dp[l][r], DP(l, k) + DP(k + 1, r));
        return dp[l][r];
    }
    
    int main(){
        T = read();
        while(T--){
            scanf("%s", M + 1);
            int len = strlen(M + 1), cnt = 0;
            for(int i = 1; i <= len; i++)
                if(M[i] == M[i - 1]) sze[cnt]++;
                else sze[++cnt] = 1, S[cnt] = M[i]; 
            memset(dp, -1, sizeof dp);
            wr(DP(1, cnt)), putchar('
    ');
        }
        return 0;
    }
    
  • 相关阅读:
    本地连接显示受限制,无法连接网络
    【Vegas原创】服务器可以上网,客户端获取DHCP后,无法上网的问题解决
    【Vegas原创】AD中域用户密码策略不生效的解决方案
    【Vegas原创】网页中英文自动/手动切换方法
    【Vegas原创】XP的administrator用户被停用的解决方法
    【Vegas原创】“光驱无法访问,函数不正确”解决方法
    去除flash边框虚框的方法代码
    【Vegas原创】远程桌面下重启xp系统的命令
    ORA00054: 资源正忙, 但指定以 NOWAIT 方式获取资源 解决方法
    【Vegas原创】BugFree删除项目的方法
  • 原文地址:https://www.cnblogs.com/CzYoL/p/7683215.html
Copyright © 2011-2022 走看看