zoukankan      html  css  js  c++  java
  • HDU 2167 状压dp方格取数

    题意:给出一个数表,规定取出一个数后周围的八个数都不可取,求可获得的最大数字和
    思路:状态压缩dp,每一行的取数方法为状态,显然,由于取数规则的限制,可取的状态并不是
    1<<size_col,而是非常有限的,我们可以预处理出状态(不超过1600个),大大降低时间复杂度,
     
    运行时间:140ms

    #include <bits/stdc++.h>
    using namespace std;
    int dp[16][1600],sta[1600],len,n;
    int g[15][15];
    void init()
    {
        for(int i=0;i<(1<<15);i++)if(!(i&(i<<1))&&!(i&(i>>1)))sta[len++]=i;//预处理出所有可取状态
    }
    
    int Res[16][1600];//加个记忆化,避免重复的计算
    inline int calstatus(int row,int sta,int j)//计算出row行这个状态所有数字的的sum
    {
        if(Res[row][j])
            return Res[row][j];
        int res=0;
        for(int j=0;j<n;j++){
            if(sta&1)
            {
                res+=g[row][j];
            }
            sta>>=1;
        }
        return Res[row][j]=res;
    }
    int main()
    {
        init();
        while (n=0,~scanf("%d",&g[0][n++]))
        {
            memset(Res,0,sizeof(Res));
            memset(dp,0, sizeof(dp));//初始化
            //坑爹输入部分
            while (true)
            {
                scanf("%d",&g[0][n++]);
                if(getchar()=='\n')break;
            }
            for(int i=1;i<n;i++)
                for(int j=0;j<n;j++)scanf("%d",&g[i][j]);
            //第一行预处理
            for(int i=0;i<n;i++)
                for(int j=0;j<len&&sta[j]<(1<<n);j++)dp[0][j]=calstatus(0,sta[j],j);
            int ans=0;
            for(int i=1;i<n;i++)
            {
                for(int j=0;j<len&&sta[j]<(1<<n);j++)
                {
                    for(int k=0;k<len&&sta[k]<(1<<n);k++)
                        if(!(sta[k]&(sta[j]<<1))&&!(sta[k]&(sta[j]>>1))&&!(sta[k]&sta[j])){//左移右移与不移,两个状态都不冲突,进行状态转移
                            dp[i][k]=max(dp[i][k],dp[i-1][j]+calstatus(i,sta[k],k));
                            ans=max(ans,dp[i][k]);
                        }
                }
            }
            printf("%d\n",ans);
        }
        return 0;
    }
  • 相关阅读:
    使用Idhttp.get('') 造成假死(堵塞),请问线程idhttp怎么才能做到不出错?
    mysql 修改字段类型
    Delphi完成的断点续传例子 转
    断点续传的例子
    甲状腺癌怎样早发现 可B超检查
    DELPHI高性能大容量SOCKET并发(九):稳定性问题解决
    百度地图信息提示框的修改 转
    delphi 调用百度地图WEBSERVICE转换GPS坐标 转
    delphi 调用百度地图api
    Gedit
  • 原文地址:https://www.cnblogs.com/xusirui/p/9741387.html
Copyright © 2011-2022 走看看