1、给出一个包含$n$个元素的数组$x$,构造出一个有向无环图满足从节点$i$出发可以访问到的节点数为$x_{i}$。
思路:按照$x$从小到大排序。然后从前向后处理,当前节点依次与前面已经处理的节点连边。
#include <iostream> #include <map> #include <string> #include <stdio.h> #include <vector> #include <set> #include <algorithm> #include <string.h> #include <fstream> #include <sstream> using namespace std; const int N=555; const int mod=998244353; int get(long long x) { int cnt=0; for(int i=0;i<55;++i) { if(x&(1ll<<i)) ++cnt; } return cnt; } class DAGConstruction { public: vector <int> construct(vector <int> x) { const int n=(int)x.size(); long long f[55]; memset(f,0,sizeof(f)); vector<int> ans,V; vector<pair<int,int>> p; for(int i=0;i<n;++i) { f[i]=1ll<<i; p.push_back(make_pair(x[i],i)); } sort(p.begin(),p.end()); for(int i=0;i<(int)p.size();++i) { int c=p[i].first; int u=p[i].second; for(int j=0;j<(int)V.size();++j) { int t=V[V.size()-1-j]; if(get(f[u]|f[t])<=c) { f[u]|=f[t]; ans.push_back(u); ans.push_back(t); } } V.push_back(u); if(get(f[u])<c) return vector<int>(1,-1); } return ans; } };
2、在$x$ 轴上有$n$个点A,$x$轴上方有$n$个点B,A集合中的每个点在B集合中的每个点找到一个匹配点,B集合中每个点只能与A中的一个点匹配,使得$n$条线段任意两条线段不相交。问有多少种方法。
思路:将B集合按照$y$坐标排序。A集合按照$x$排序。每次枚举A中的一个点与B中最高的点连线,这样分成两段,继续进行这样的匹配。
#include <iostream> #include <map> #include <string> #include <stdio.h> #include <vector> #include <set> #include <algorithm> #include <string.h> #include <fstream> #include <sstream> using namespace std; const int N=555; const int mod=1000000007; vector<int> D,X,Y; int n; map<vector<int>,int> mp[55][55]; int dfs(int L,int R,vector<int> S) { if(S.size()<=1) return 1; if(mp[L][R].count(S)) return mp[L][R][S]; long long ans=0; for(int i=L;i<=R;++i) { const int x1=X[S.back()]-D[i]; const int y1=Y[S.back()]; vector<int> ls,rs; int ok=1; for(int j=0;j<(int)S.size()-1;++j) { const int x0=X[S[j]]-D[i]; const int y0=Y[S[j]]; const int sgn=x0*y1-x1*y0; if(sgn==0) { ok=0; break; } if(sgn<0) ls.push_back(S[j]); else rs.push_back(S[j]); } if(ok&&ls.size()==i-L&&rs.size()==R-i) ans+=1ll*dfs(L,i-1,ls)*dfs(i+1,R,rs)%mod; } return mp[L][R][S]=ans%mod; } class CoastGuard { public: int count(vector <int> d, vector <int> x, vector <int> y) { n=(int)d.size(); D=d; sort(D.begin(),D.end()); vector<pair<int,int>> p; vector<int> S; for(int i=0;i<n;++i) { p.push_back(make_pair(y[i],x[i])); S.push_back(i); } sort(p.begin(),p.end()); for(int i=0;i<n;++i) { Y.push_back(p[i].first); X.push_back(p[i].second); } return dfs(0,n-1,S); } };