zoukankan      html  css  js  c++  java
  • hdu1565 用搜索代替枚举找可能状态或者轮廓线解(较优),参考poj2411

    这题用直接枚举是超时的,必须要用搜索来搜索出所有可能的状态,然后再进行枚举

    这是较慢的做法

    /*
    方格取数,相邻格子的数不可取,问最多取到的和是什么 
    有点类似炮兵布阵,先打出所有可能的状态,然后dp[i][j]表示前i行在状态v[j]下的最大和 
    dp[i][j]由dp[i-1][t]推出,v[t]是和v[j]兼容的状态 
    */
    #include<bits/stdc++.h>
    using namespace std;
    int mp[25][25],n,dp[21][200000];
    int v[200000],tot;
    vector<int>sum[25];//sum[i][j]表示第i行在状态v[j]下的和 
    inline int legal(int j){
        if( j&(j<<1) )return false;
        return true;
    }
    inline int cal(int s,int k){//状态s对应的数值 
        int res=0;
        for(int i=1;i<=n;i++)
            if( s&(1<<(i-1)) )res+=mp[k][n-i+1]; 
            return res;
    }
    void init(){
        tot=0;
        for(int j=0;j<=(1<<n)-1;j++)
            if(legal(j))v[tot++]=j;
    }
    
    int main(){
        while(cin>>n){
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)cin>>mp[i][j];
            init();
            memset(dp,0,sizeof dp);
            for(int i=0;i<tot;i++)
                dp[1][i]=cal(v[i],1);
                
            for(int i=2;i<=n;i++)
                for(int j=0;j<tot;j++){//枚举i行的状态 
                    for(int k=0;k<tot;k++){//枚举k行的状态
                        if( v[k]&v[j] )continue; 
                        dp[i][j]=max(dp[i][j],dp[i-1][k]+cal(v[j],i));
                    }
                }
            
            int ans=0;
            for(int i=0;i<tot;i++)
                ans=max(ans,dp[n][i]);
            printf("%d
    ",ans);
        }
    } 
  • 相关阅读:
    Centos7下搭建SVN
    Ubuntu设置telnet 远程登录(root权限)
    E: 无法打开锁文件 /var/lib/dpkg/lock-frontend
    使用ICMP搭建隧道(PingTunnel)
    Centos7安装Redis
    idea 激活方法
    Chrome 浏览器安装 ChroPath 插件
    jmeter引入外部jar包的方法
    maven安装
    eclipse集成 json editor plugin插件
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10361813.html
Copyright © 2011-2022 走看看