1. 程式人生 > >HDU 1565 方格取數(1)(狀態壓縮DP)

HDU 1565 方格取數(1)(狀態壓縮DP)

挺簡單的一個狀壓DP,因為一點小失誤搞了好久。。

先按最大值跑一遍getState可以知道一行可以有多少種狀態,就是MAX_K。狀態轉移方程:dp[s][i] = max(dp[s][i], dp[j][i - 1] + getSum(state[s], i)),dp[s][i]表示第i行在狀態state[s]下可以取到的前i行的最大值。

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

const int MAX_N = 20;
const int MAX_S = (1 << MAX_N) + 100;
const int MAX_M = MAX_N + 5;
const int MAX_K = 17745 + 1000;

int dp[MAX_K][MAX_M];
int _map[MAX_M][MAX_M];
int state[MAX_K];
int n, cnt;

bool is_ok(int s)
{
    if(s & (s << 1))
        return false;
    return true;
}

int getSum(int s, int i)
{
    int res = 0;
    int k = 0;
    while(s > 0)
    {
        if(s & 1)
            res += _map[i][k];
        s = s >> 1;
        k++;
    }
    return res;
}
int getState()
{
    cnt = 0;
    int len = (1 << n) - 1;
    for(int s = 0; s <= len; s++)
        if(is_ok(s))
            state[cnt++] = s;
    return cnt;
}
int main()
{
    //freopen("in.txt", "r", stdin);
    while(scanf("%d", &n) != EOF)
    {
        memset(dp, 0, sizeof(dp));
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
                scanf("%d", &_map[i][j]);
        getState();
        int _max = 0;
        for(int s = 0; s < cnt; s++)
            dp[s][0] = getSum(state[s], 0);
        for(int i = 1; i < n; i++)
        {
            for(int s = 0; s < cnt; s++)
            {
                for(int j = 0; j < cnt; j++)
                {
                    if(state[s] & state[j])
                        continue;
                    dp[s][i] = max(dp[s][i], dp[j][i - 1] + getSum(state[s], i));
                }
            }
        }
        for(int s = 0; s < cnt; s++)
            _max = max(_max, dp[s][n - 1]);
        printf("%d\n", _max);
    }
    return 0;
}


相關推薦

HDU 1565 方格(1)(狀態壓縮DP)

挺簡單的一個狀壓DP,因為一點小失誤搞了好久。。 先按最大值跑一遍getState可以知道一行可以有多少種狀態,就是MAX_K。狀態轉移方程:dp[s][i] = max(dp[s][i], dp[j][i - 1] + getSum(state[s], i)),dp[s

HDU 1565 方格(1) 狀態壓縮DP

題目大意: 從n*n的矩陣中取出一些數使得這些數互不相鄰,問最大和為多少 大致思路: 明顯的狀態壓縮DP,每兩行之間的狀態轉移,這裡受到記憶體限制只開兩個陣列來表示當先行和下一行來進行轉移,原本想用vector來記錄那兩個狀態之間可以轉換的,但是受到記憶體限制還是用時間換

HDU 1565 方格(1)(插頭DP||狀態壓縮

Problem Description 給你一個n*n的格子的棋盤,每個格子裡面有一個非負數。 從中取出若干個數,使得任意的兩個數所在的格子沒有公共邊,就是說所取的數所在的2個格子不能相鄰,並且取出的數的和最大。 Input 包括多個測試例項,每個測試例項包括一

hdu 1565 方格(1) 位壓縮動態規劃

hdoj 1565 dp 方格取數(1) Time Limit: 1000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1162    

HDU 1565 - 方格(1) - [狀壓DP][網絡流 - 最大點權獨立集和最小點權覆蓋集]

printf 一個 cnblogs ret com bool limit .net amp 題目鏈接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory

HDU1565:方格(1) (狀態壓縮DP)

Problem Description 給你一個n*n的格子的棋盤,每個格子裡面有一個非負數。 從中取出若干個數,使得任意的兩個數所在的格子沒有公共邊,就是說所取的數所在的2個格子不能相鄰,並且取出的數的和最大。   Input 包括多個測試例項,每個測試例項包括一個整數n

HDU 1565 方格(1) (狀態壓縮DP入門題 2)(待更新)

Problem Description 給你一個n*n的格子的棋盤,每個格子裡面有一個非負數。從中取出若干個數,使得任意的兩個數所在的格子沒有公共邊,就是說所取的數所在的2個格子不能相鄰,並且取出的數的和最大。Input 包括多個測試例項,每個測試例項包括一個整數n 和n*n

hdu 1565 方格(1)(狀態壓縮DP

終於可以寫題解了。因為一個細節上的失誤,讓我重新修改的程式碼一直通不過測試,鬱悶。 程式碼毫無參考價值,剛學的狀態壓縮DP,程式碼寫得很難看。 #include<stdio.h> #inc

HDU 1565 方格(1)

can getchar class target 方格取數 set ems n-k ++ 鏈接 思路   狀壓dp,dp[i][j]:表示到第i行,當前狀態為s的最大值。預處理在每一行選的時候可能的狀態,及這個狀態的價值。   轉移方程:dp[i][j] = max(

HDU 1565 方格(1) (狀壓DP

http://acm.hdu.edu.cn/showproblem.php?pid=1565 #include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring>

HDU 1565 方格(1)(最大點權獨立集)

題目大意:給你一個n*n的格子的棋盤,每個格子裡面有一個非負數。 從中取出若干個數,使得任意的兩個數所在的格子沒有公共邊,就是說所取的數所在的2個格子不能相鄰,並且取出的數的和最大。 解題思路:最大點權獨立集,關鍵是怎麼建圖了,我們可以採用染色的思想對這張圖

HDU 1565 方格(1)(最大獨立點集)

題目地址 題意:中文。 思路:我是實在想不懂這類題目為什麼可以轉化為網路流來寫,於是我看了好多題解。然後發現因為相鄰的兩個點是不能同時選的,然後這樣就劃分成了兩類點,用奇偶建點的方法,可以很明白的寫出這個模型,因為相鄰兩點的橫縱座標加起來一定是一奇一偶的。然

hdu 1565 方格(1)【最大流】

程式碼: #include <iostream> #include <algorithm> #include <set> #include <map> #include <string.h> #i

hdu 1565 方格(1)(最小割)

方格取數(1) Problem Description 給你一個n*n的格子的棋盤,每個格子裡面有一個非負數。 從中取出若干個數,使得任意的兩個數所在的格子沒有公共邊,就是說所取的數所在的2個格子不能相鄰,並且取出的數的和最大。 Input 包括多個測試例項,每個測試例項

hdu 1565 方格(狀壓dp

給你一個n*n的格子的棋盤,每個格子裡面有一個非負數。  從中取出若干個數,使得任意的兩個數所在的格子沒有公共邊,就是說所取的數所在的2個格子不能相鄰,並且取出的數的和最大。 Input 包括多個測試例項,每個測試例項包括一個整數n 和n*n個非負數(n<=20)

HDU1565方格(1)

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11226    Accepted Submission(

hdu 1565 方格1)【狀壓dp

方格取數(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7585    Accepted Subm

hdu 1565 方格(2)(網絡流之最大點權獨立集)

href aps flow bit 明顯 log sum dir 一個 題目鏈接:hdu 1565 方格取數(2) 題意: 有一個n*m的方格,每個方格有一個數,現在讓你選一些數。使得和最大。 選的數不能有相鄰的。 題解: 我們知道對於普通二分圖來說,最大獨立點集 + 最小

1565 方格(1)

題目: 給你一個n*n的格子的棋盤,每個格子裡面有一個非負數。  從中取出若干個數,使得任意的兩個數所在的格子沒有公共邊,就是說所取的數所在的2個格子不能相鄰,並且取出的數的和最大。 Input

HDU 1565 方格 題解

【題目】: Problem Description 給你一個n*n的格子的棋盤,每個格子裡面有一個非負數。 從中取出若干個數,使得任意的兩個數所在的格子沒有公共邊,就是說所取的數所在的2個格子不能相鄰,並且取出的數的和最大。 Input 包括多個測試例項,每個測