(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,分別表示棋盤的行...