HDU 6289 尋寶遊戲 詳解 DP

2021-08-21 12:17:01 字數 1942 閱讀 4704

小q最近迷上了一款尋寶遊戲,這款遊戲中每局都會生成乙個n×m的網格地圖,從上往下依次編號為第1行到第n行,從左往右依次編號為第1列到第m列。每個格仔上都有不同數量的金幣,第i行第j列的格仔上的金幣數量為ai,j。

小q一開始位於(1,1),每次他可以往右或者往下走,每當他經過某個格仔時,他就可以拿走這個格仔上的所有金幣。小q不能走出這個地圖,當小q不能再行動時,遊戲結束。顯然當且僅當小q位於(n,m)時,遊戲才會結束。

一輪遊戲的得分為這一輪中收集到的金幣總量,而在遊戲開始前,因為小q是超級vip使用者,所以他有k次機會交換某兩個格仔中的金幣數。這k次機會不一定要用完,請寫乙個程式幫助小q在一輪內拿到盡可能多的金幣。

第一行包含乙個正整數t(1≤t≤10),表示測試資料的組數。

每組資料第一行包含三個整數n,m,k(2≤n,m≤50,0≤k≤20),分別表示地圖的長寬以及交換的次數。

接下來n行,每行m個整數ai,j(0≤ai,j≤106),依次表示每個格仔中金幣的數量。

output

對於每組資料,輸出一行乙個整數,即能收集到的金幣數量的最大可能值。

2 3 4 0

1 2 3 4

9 8 7 6

5 4 7 2

5 5 1

9 9 9 0 0

0 0 9 0 0

0 0 0 0 0

0 0 9 0 0

9 0 9 9 9

34 81

——————

首先考慮如何暴力求出最優解決方案,一種很簡單的做法就是列舉每一種走法,然後用改走法路徑外的數值從大到小替換路徑內從小到達的數值。——必tle

參考了別人的在做法,使用動態規劃解決這個問題

狀態dp[x][y][used][blank]表示當前正在座標(x,y),使用了used次交換將路徑外的數值交換到路徑內,但是目前只有blank個數被交換出去。顯而易見used==blank的狀

態才是最終情況下的正確狀況。

dp的做法本質上還是在一定的走法路徑上將路徑內的數值和路徑外的數值進行替換,我們需要知道如何能在狀態轉移中執行替換的操作,並且乙個格仔不會被替換到路徑內多次,且所有路徑外的格仔都要被考慮到。

我的具體轉移方法就是,當從座標(x-1,y)轉移到(x,y)時,考慮[x-1][y+1 to m]這段區間數值和[x][1 to y-1]這段區間的數值替換到路徑內,向右走的時候不考慮替換操作,這樣就能保證每個格仔都被考慮到且不會被多次考慮到了。

具體轉移方式見**。

#include 

using namespace std;

typedef long long ll;

const int maxn=55;

const int maxk=25;

const int maxm=100005;

const int maxe=2

*1e5+115;

const int mod=1e9+7;

const int inf=0x3f3f3f3f;

int n,m,k;

int dp[maxn][maxn][maxk][maxk];

intma[maxn][maxn];

intvec[maxn];

int tot;

inline bool cmp(int a,int b)

int main()

}dp[0][0][0][0]=ma[0][0];

dp[0][0][0][1]=0;

for(int

x=0;x

x++)

}if(y)

dp[x][y][used][blank]=ans;}}

}}

int ans=0;

for(int i=0;i<=k;i++)

printf("%d\n",ans);

}return

0;}

真正的628總結

今天上午學了dfs序,反向存在棧裡利用 dfs回溯當開頭,邊雙聯通分量任兩點間有兩條不重邊的路徑,點雙聯通分量則是不重 三聲 點,可以利用刪點 邊的方式求。關於 2sat 問題,乙個點為真一定導向下一條邏輯邊對應點為真,但是為假則不一定下一條為假。取值時由離根節點近的開始取,同時可以把乙個點拆為幾個...

6 28 計算機基礎

1.機器語言 直接和計算機溝通 直接操作硬體 2.組合語言 簡單的英文本元代替二進位制數 直接操作硬體 3.高階語言 a.編譯型 c 一次編譯多次使用 優點 執行效率高 缺點 開發效率低 b.解釋型 python 一行一行的翻譯 優點 開發效率高 缺點 執行效率低 執行效率 學習效率 機器語言 組合...

刷題筆記 LeetCode 628

給你乙個整型陣列 nums 在陣列中找出由三個數組成的最大乘積,並輸出這個乘積。這是筆者的第一篇部落格,題目簡答,略顯粗糙。筆者看到這題時,頭腦簡單,直接使用sort排序,之後返回最大的三個數的乘積,這明顯是錯誤的,沒有考慮到負負得正,屬實丟臉。稍加思考之後,我分為兩種情況來進行討論。先將整個陣列進...