zoukankan      html  css  js  c++  java
  • srm 578 dv2 1000pt

    这题我做了好几天(真是弱),刚开始不会,然后苏神教了我好长时间,但是我智商太低!还是不懂。。

    于是我不得已去看题解。。我一直觉得tc那个神马vexorian写的题解有点反人类,所以一直不想看,结果这场不是他写的(囧)。。一看就懂了

    思路嘛。。大概就是一个位置可以放0,可以放1,但是放0有区间限制,怎么办呢?用一个last记录一下前一个1,如果不在以i结尾的区间内,那这个位置就必须放1了。。

    贴个代码

    #include <vector>
    #include <list>
    #include <map>
    #include <set>
    #include <deque>
    #include <stack>
    #include <bitset>
    #include <algorithm>
    #include <functional>
    #include <numeric>
    #include <utility>
    #include <sstream>
    #include <iostream>
    #include <iomanip>
    #include <cstdio>
    #include <cmath>
    #include <cstdlib>
    #include <ctime>
    #include <cstring>
    # define MOD 1000000007
    using namespace std;
    
    vector<int> v[310];
    int n,d[310][310];
    class WolfInZooDivTwo {
    public:
        int count(int, vector <string>, vector <string>);
    };
    int dp(int last,int at)
    {
        if (at>n) return 1;
        if (d[last][at]!=-1) return d[last][at];
        int i,flag=0; d[last][at] = 0;
        for (i=0;i<v[at].size();++i) 
            if (v[at][i]>last)
                flag = 1;
        if (!flag) d[last][at] = dp(last,at+1)%MOD;
        d[last][at] += dp(at,at+1)%MOD;
        d[last][at] %= MOD;
        return d[last][at];
    }
    int WolfInZooDivTwo::count(int N, vector <string> L, vector <string> R) 
    {
        int i,j,l,r;
        string SL = "",SR = "";
        for (i=0;i<L.size();++i) SL += L[i];
        for (i=0;i<R.size();++i) SR += R[i];
        stringstream ss1(SL);
        stringstream ss2(SR);
        while (ss1>>l)
        {
            ss2>>(r);
            cout<<l<<" "<<r<<endl;
            v[r+1].push_back(l+1);
        }
        memset(d,-1,sizeof(d));
        n = N;
        return dp(0,1);
    }
    View Code

     相同思想的还有dv1 500pt,这次要求每个区间最多只能放2个,如果用前一题的做法用2个变量来记录前2个1的话,空间超了。如果这个位置放1,还要扫描所有区间看看有木有违背,复杂度就是300^4左右吧,太慢。

    不妨换一个角度,只记录前1个1,如果这个位置放1,那么直接跳到下一个能放1的区间作为起始点,这样空间n^2,时间O(nm^2)

    #include <vector>
    #include <list>
    #include <map>
    #include <set>
    #include <deque>
    #include <stack>
    #include <bitset>
    #include <algorithm>
    #include <functional>
    #include <numeric>
    #include <utility>
    #include <sstream>
    #include <iostream>
    #include <iomanip>
    #include <cstdio>
    #include <cmath>
    #include <cstdlib>
    #include <ctime>
    #include <cstring>
    # define MOD 1000000007
    using namespace std;
    typedef pair<int,int> pii;
    vector<pii> v;
    int n,d[310][310];
    class WolfInZooDivOne {
    public:
        int count(int, vector <string>, vector <string>);
    };
    int dp(int last,int at)
    {
        if (at>n) return 1;
        if (d[last][at]!=-1) return d[last][at];
        int i,t=at; d[last][at] = 0;
        d[last][at] += dp(last,at+1)%MOD;
        for (i=0;i<v.size();++i)
            if (v[i].first<=last&&v[i].second>=at)
                t = max(t,v[i].second);        
        d[last][at] += dp(at,t+1)%MOD;
        d[last][at] %= MOD;
        return d[last][at];
    }
    int WolfInZooDivOne::count(int N, vector <string> L, vector <string> R) 
    {
        int i,j,l,r;
        string SL = "",SR = "";
        for (i=0;i<L.size();++i) SL += L[i];
        for (i=0;i<R.size();++i) SR += R[i];
        stringstream ss1(SL);
        stringstream ss2(SR);
        while (ss1>>l)
        {
            ss2>>(r);
            v.push_back(make_pair(l+1,r+1));
        }
        memset(d,-1,sizeof(d));
        n = N;
        return dp(0,1);
    }
    View Code
  • 相关阅读:
    3、总结
    三分及小例题
    约瑟夫问题的推导
    对于联通块的处理
    扩展欧几里得与二元不定方程
    js 阻止事件捕获
    原生xhr发送JSON
    $timeout
    Angularjs Ng_repeat中实现复选框选中并显示不同的样式
    为什么用Object.prototype.toString.call(obj)检测对象类型?
  • 原文地址:https://www.cnblogs.com/1carus/p/3404237.html
Copyright © 2011-2022 走看看