zoukankan      html  css  js  c++  java
  • CQOI2018 解锁屏幕

    题目链接:戳我

    其实只有开了O2才能A.......

    就是我们看到n的范围这么小,就想到状压DP。然后我们设状态dp[i]表示状态为i的(二进制表示该点选或者不选),方案数有多少个。

    但是我们发现因为还要枚举转移下一个点,所以我们还要记录一下最后的那个点是什么。

    于是我们修改状态为(dp[i][j])表示当前状态为i,最后一个点的编号为j的,方案数有多少个。

    然后(O(2^n*n^2)).......吧

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #define MAXN 21
    #define eps 1e-7
    #define mod 100000007
    using namespace std;
    int n,m,ans;
    int dp[1<<MAXN][MAXN];
    struct Node{int x,y;}node[MAXN];
    vector<int>mid[MAXN][MAXN];
    inline bool cmp(struct Node a,struct Node b)
    {
        if(a.x==b.x) return a.y<b.y;
        return a.x<b.x;
    }
    inline bool check(int a,int b,int c)
    {
        double k1,k2;
        if(node[a].x==node[b].x&&node[a].x==node[c].x) return true;
        else if(node[a].x==node[c].x||node[a].x==node[b].x) return false;
        k1=1.0*(node[a].y-node[b].y)/(node[a].x-node[b].x);
        k2=1.0*(node[a].y-node[c].y)/(node[a].x-node[c].x);
        if(fabs(k1-k2)<eps) return true;
        else return false;
    }
    inline bool more_than_4(int x)
    {
        int cur_ans=0;
        for(int i=0;i<n;i++)
            if(x&(1<<i))
                cur_ans++;
        return cur_ans>=4;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
                scanf("%d%d",&node[i].x,&node[i].y);
        sort(&node[1],&node[n+1],cmp);
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++)
                for(int k=i+1;k<=j-1;k++)
                    if(check(i,j,k)==true)
                        mid[i][j].push_back(k);
        for(int i=1;i<=n;i++) dp[1<<(i-1)][i]=1;
        for(int i=1;i<(1<<n);i++)
        {
            for(int j=1;j<=n;j++)
            {
                if((i>>(j-1))&1) continue;
                int s=(i|(1<<(j-1)));
                for(int k=1;k<=n;k++)
                {
                    if(k==j) continue;
                    int x=min(j,k),y=max(j,k),flag=0;
                    for(int t=0;t<mid[x][y].size();t++)
                        if(!((i>>(mid[x][y][t]-1))&1)){flag=1;break;}
                    if(flag==1) continue;
                    dp[s][j]=(dp[s][j]+dp[i][k])%mod;
                }
            }
        }
        for(int i=1;i<(1<<n);i++)	
            if(more_than_4(i))
                for(int j=1;j<=n;j++)
                    ans=(ans+dp[i][j])%mod;
        printf("%d
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    627. Swap Salary
    176. Second Highest Salary
    596. Classes More Than 5 Students
    183. Customers Who Never Order
    181. Employees Earning More Than Their Managers
    182. Duplicate Emails
    175. Combine Two Tables
    620. Not Boring Movies
    595. Big Countries
    HDU 6034 Balala Power! (贪心+坑题)
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10909237.html
Copyright © 2011-2022 走看看