zoukankan      html  css  js  c++  java
  • NOIP 2016 愤怒的小鸟 题解

    一道状压dp题,但是竟然可以搜索搜过!!(儒雅随和)。

    代码(爆搜)

    #include<bits/stdc++.h>
    using namespace std;
    const double eps=1e-8;
    int T,n,m,ans;
    double x[25],y[25],a[25],b[25];
    bool book[25];
    bool cheak(double a,double b){
        return (fabs(a-b)<eps);
    }
    int clu(){
        int tmp=0;
        for(int i=1;i<=n;++i){
            if(book[i]) tmp++;
        }
        return tmp;
    }
    void dfs(int c,int k){
        if(k+clu()>=ans) return;
        if(c>n){
            ans=k+clu();
            return;
        }
        bool flag=false;
        for(int i=1;i<=k;++i){
            if(cheak(a[i]*x[c]*x[c]+b[i]*x[c],y[c])){
                flag=true;
                dfs(c+1,k);
                break;
            }
        }
        if(!flag){
            for(int i=1;i<=n;++i){
                if(!cheak(x[i],x[c])&&book[i]){
                    double a1=(x[i]*y[c]-y[i]*x[c])/(x[c]*x[i]*(x[c]-x[i]));
                    double b1=(y[c]-x[c]*x[c]*a1)/x[c];
                    if(a1<0){
                        a[k+1]=a1;
                        b[k+1]=b1;
                        book[i]=0;
                        dfs(c+1,k+1);
                        book[i]=1;
                    }
                }
            }
            book[c]=1;
            dfs(c+1,k);
            book[c]=0;
        }
         
    }
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d %d",&n,&m);
            for(int i=1;i<=n;++i){
                scanf("%lf %lf",&x[i],&y[i]);
            }
            memset(book,0,sizeof(book));
            ans=n;
            if(m==1) ans=n/3+2;
            else if(m==2) ans=(2*n)/3+1;
            dfs(1,0);
            printf("%d
    ",ans);
        }
    } 
    

    状压dp

    #include<bits/stdc++.h>
    using namespace std;
    const double eps=1e-8;
    int dp[262144],st[200],num;
    double x[25],y[25];
    int t,n,m;
    bool cheak(double a,double b){
        return fabs(a-b)<eps;
    }
    void init(){
        memset(dp,0x3f,sizeof(dp));
        memset(st,0,sizeof(st));
        num=0;
        dp[0]=0;
        for(int i=1;i<=n;++i){
            for(int j=i+1;j<=n;++j){
                if(!cheak(x[i],x[j])){
                    double a1=(x[i]*y[j]-y[i]*x[j])/(x[i]*x[j]*(x[j]-x[i]));
                    double b1=(y[j]-a1*x[j]*x[j])/x[j];
                    if(a1<0){
                        ++num;
                        for(int k=1;k<=n;++k){
                            if(cheak(a1*x[k]*x[k]+b1*x[k],y[k])){
                                st[num]|=(1<<(k-1));
                            }
                        }
                    }
                }
            }
        }
    }
    void solve(){
        init();
        for(int s=0;s<(1<<n);++s){
            for(int i=1;i<=num;++i) dp[s|st[i]]=min(dp[s|st[i]],dp[s]+1);
            for(int i=1;i<=n;++i) dp[s|(1<<(i-1))]=min(dp[s|1<<(i-1)],dp[s]+1);
        }
    }
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d %d",&n,&m);
            for(int i=1;i<=n;++i){
                scanf("%lf %lf",&x[i],&y[i]);
            }
            solve();
            printf("%d
    ",dp[(1<<n)-1]);
        }
        return 0;
    }
    
  • 相关阅读:
    Cookie练习
    JS写九九乘法表
    对GridView实现分页
    对GridView的行加颜色并弹出Kindeditor
    对Dictionary的理解
    一、android 开发环境大搭建
    main方法的测试
    main 方法的书写(1)
    由InvocationTargetException引发的思考
    汇编学习笔记之处理器体系结构
  • 原文地址:https://www.cnblogs.com/donkey2603089141/p/11416729.html
Copyright © 2011-2022 走看看