(P2774 方格取數問題) 狀壓DP

2022-04-01 04:39:14 字數 1182 閱讀 9441

(p2774 方格取數問題)(狀壓dp)。這是一道用狀壓dp似乎ac無望的題。。。

畢竟題解都是網路流。。。#>#

不過用這個題學會了dp滾動陣列的巧妙寫法

在乙個有 m*n 個方格的棋盤中,每個方格中有乙個正整數。現要從方格中取數,使任意 2 個數所在方格沒有公共邊,且取出的數的總和最大。試設計乙個滿足要求的取數演算法。對於給定的方格棋盤,按照取數要求程式設計找出總和最大的數。

輸入格式:

第 1 行有 2 個正整數 m 和 n,分別表示棋盤的行數和列數。接下來的 m 行,每行有 n 個正整數,表示棋盤方格中的數。

輸出格式:

程式執行結束時,將取數的最大總和輸出

輸入樣例#1:

3 31 2 3

3 2 3

2 3 1

輸出樣例#1:

11與「互不侵犯」不同的地方:

很明顯的是,求的方向不同,所以dp方程不同,但其他方面的思想都基本一致。本題要把每種方案的結果算出來取最大值。 初始化的一點小小的不同:每種方案對應的二進位制數不僅要用於判斷條件(無公共邊),還有用於計算每種方案的代數和while(t)滾動陣列優化:注意到每一行的f都由上一行轉移而來,所以可以用滾動陣列。但是不能像揹包問題那樣無腦,因為無論你怎樣調整迴圈的順序,總是無法保證f陣列依然儲存上一行的結果。所以需要用另乙個陣列記錄每一行dp完成後的值,下一行dp時呼叫這個陣列裡的值,而不是直接呼叫f。但是這樣做需要每一行dp完成後將值賦到另乙個陣列裡,複雜度高。乙個比較巧妙的辦法是,將f多開一維,新開的這一維只有0和1,代表每一行的準確值和計算值,即原來的f陣列和新開的陣列。每一次算完後,將0或1與1異或,這樣0變成1,1變成0,實現兩個陣列的相互呼叫。#include

#include

#include

#include

#include

using namespace std;

int n,m;//正整數 m 和 n,分別表示棋盤的行數和列數

int p[21][21];

int s[21][2000],num[2000][2000];

int st;

long long f[2][2000];

void _state()

s[a][st++]=i;}}

/* for(int i=0;i<=n;++i){

for(int j=0;j<=st;++j) cout<

(P2774 方格取數問題)《狀壓DP

這是一道用狀壓dp似乎ac無望的題。畢竟題解都是網路流。不過用這個題學會了dp滾動陣列的巧妙寫法 在乙個有 m n 個方格的棋盤中,每個方格中有乙個正整數。現要從方格中取數,使任意 2 個數所在方格沒有公共邊,且取出的數的總和最大。試設計乙個滿足要求的取數演算法。對於給定的方格棋盤,按照取數要求程式...

P2774 方格取數問題

題目描述 在乙個有 m n 個方格的棋盤中,每個方格中有乙個正整數。現要從方格中取數,使任意 2 個數所在方格沒有公共邊,且取出的數的總和最大。試設計乙個滿足要求的取數演算法。對於給定的方格棋盤,按照取數要求程式設計找出總和最大的數。輸入格式 第 1 行有 2 個正整數 m 和 n,分別表示棋盤的行...

P2774 方格取數問題

none 在乙個有 m n 個方格的棋盤中,每個方格中有乙個正整數。現要從方格中取數,使任意 2 個數所在方格沒有公共邊,且取出的數的總和最大。試設計乙個滿足要求的取數演算法。對於給定的方格棋盤,按照取數要求程式設計找出總和最大的數。輸入格式 第 1 行有 2 個正整數 m 和 n,分別表示棋盤的行...