topcoder srm 703 div1 -3

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);
    }
};

  

原文地址:https://www.cnblogs.com/jianglangcaijin/p/6701401.html