zoukankan      html  css  js  c++  java
  • HDOJ 2167 Pebbles (状态压缩dp)

    题意:给你一个n*n的矩阵,让你从矩阵中选择一些数是的他们的和最大,规则是:相邻的两个数不能同时取,位置为(i,j)的数与(i+1,j),(i-1,j),(i,j+1),(i,j-1),(i+1,j+1),(i+1,j-1),(i-1,j+1),(i-1,j-1)相邻。

    思路:很常见的状态压缩dp,设dp[i][j]表示前i行,第i行状态为j时的最大和,那么dp[i][j] = max(dp[i-1][k]) + (该状态下取第i行的那些数的和)。

    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int MAXN = 16;
    const int MAXM = 1700;
    int status[MAXM],cnt;
    int dp[MAXN][MAXM],mat[MAXN][MAXN];
    void createStatus(int n){
        cnt = 0;
        int up = (1 << n);
        for(int i = 0;i < up;i ++){
            if(i & (i << 1)) continue;
            status[cnt++] = i;
        }
    }
    int calSum(int n,int m){
        int ret = 0;
        for(int i = 0;i < 16;i ++)
            if(m & (1 << i)) ret += mat[n][i];
        return ret;
    }
    void init(int n){
        createStatus(n);
        memset(dp,0,sizeof dp);
        for(int i = 0;i < cnt;i ++) dp[0][i] = calSum(0,status[i]);
    }
    bool isValid(int n,int m){
        if(n & m) return false;
        if((n << 1) & m || (m << 1) & n) return false;
        return true;
    }
    void work(int n){
        init(n);
        for(int i = 1;i < n;i ++){
            for(int j = 0;j < cnt;j ++){
                for(int k = 0;k < cnt;k ++){
                    if(!isValid(status[j],status[k])) continue;
                    dp[i][j] = max(dp[i-1][k],dp[i][j]);
                }
                dp[i][j] += calSum(i,status[j]);
            }
        }
        int ans = 0;
        for(int i = 0;i < cnt;i ++) ans = max(ans,dp[n-1][i]);
        printf("%d
    ",ans);
    }
    int main(){
        char str[MAXN*4];
        //freopen("in.cpp","r",stdin);
        while(gets(str)){
            int n(0),len(strlen(str));
            for(int i = 0;i < len;i += 3){
                mat[0][n++] = (str[i]-'0')*10 + str[i+1] - '0';
            }
            for(int i = 1;i < n;i ++){
                for(int j = 0;j < n;j ++) scanf("%d",&mat[i][j]);
            }
            work(n);
            getchar(),getchar();
        }
        return 0;
    }
    


  • 相关阅读:
    26. 60s快速定位服务器性能问题
    27. 性能测试总体流程
    18. Jmeter-取样器二
    17. Jmeter-取样器一
    15. Jmeter-配置元件二
    14. Jmeter-配置元件一
    13. Jmeter-定时器
    git 常用命令
    数据库常用操作
    【CSS】文字超出显示省略号&连续字符换行
  • 原文地址:https://www.cnblogs.com/anhuizhiye/p/3933131.html
Copyright © 2011-2022 走看看