首先在從乙個點,目標是向西運輸,那麼它一路走過的路徑x中可能朝西也可能朝北,但最終指向的都是西邊,畫圖可知西方同行中所有的礦點必只能向西運輸,即使是從出發就開始一路向北,最終也只能匯流進路徑x中,指向西。從該點向北的運輸,北方同列的考慮也是一樣的。我們可以預處理出從乙個點向西和向北的貢獻是什麼。
我們令dp[i][j]為前i行j列的礦石採集總數,在點(i, j)有這麼一堆礦石,我們只能二選一將其向北或者向西運輸,我們知道了一旦向西西方的所有點都必須向西,那麼這一行的貢獻對於整個dp[i][j]就是單行全向西加上這行上方dp[i - 1][j]的總和,同理向北就是單列向北的貢獻加上dp[i][j - 1]的總和,二者比較找出最優決策。
狀態轉移方程:
dp[i][j] = max(west[i][j] + dp[i - 1][j], north[i][j] + dp[i][j - 1]);
我們讀入時預處理出west[ ][ ]和north[ ][ ]陣列,然後n2 遞推即可。
ac**:
#include#define for(a, b, c) for(int a=b; a<=c; a++)
#define maxn 505
#define maxm 2000005
#define hrdg 1000000007
#define inf 2147483647
#define llinf 9223372036854775807
#define ll long long
#define pi acos(-1.0)
#define ls p<<1
#define rs p<<1|1
#define id(a, b) (a-1)*(m+1)+b
using namespace std;
int dp[maxn][maxn], west[maxn][maxn], north[maxn][maxn];
int n, m, x;
inline int read()
while(c>='0'&&c<='9')
return x*f;
}int main()
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
dp[i][j] = max(west[i][j] + dp[i - 1][j], north[i][j] + dp[i][j - 1]);
cout
}
動態規劃專題 解題報告 A
乙個經典的貨郎擔問題,加上17的範圍限制各種明示狀態壓縮,用二進位制來表示走過哪幾個城市,我們可以開乙個二維陣列dp i j 表示走過了i的城市,最後在j城市停留的距離。預處理一遍每個城市間的距離,算出dis i j 到dp i j 的狀態可以由 1 1 j k 轉移過來,比較距離儲存最優值就行,然...
動態規劃專題 解題報告 M
別的我不說了,良心題解先吹一波好吧。最重要的使這一段 假如第一位4,第二位7,三四位就可以隨便取了。設這種狀態為 2,2 意思為前兩位已經匹配上了4750的第二位。則用dp 2 2 表示 dp 100010 5 一共5 1e5種狀態 那麼 2,2 就有10種選擇 0 9 會轉移1次到 3,3 選5 ...
動態規劃專題 解題報告 D
我們先來想想n2 怎麼做,兩個n2 迴圈乙個求以i結尾的最長上公升子串行,另乙個逆序求一遍,然後列舉i,以i為中間點的長度,迴圈更新結果就有了。是不是很簡單,恭喜你tle。想都不用想必t好嗎?沒有個nlogn演算法怎麼在1e6的資料範圍面前找場子?nlo gn nlogn nlog n做法 我們其實...