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); }
相同思想的还有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); }