先從動規刷起 ,做了這麼一道題,2023年的老題,提高組第四題
//題目描述 description
設有n*n的方格圖(n<=10,我們將其中的某些方格中填入正整數,而其他的方格中則放入數字0。如下圖所示(見樣例):
某人從圖的左上角的a 點出發,可以向下行走,也可以向右走,直到到達右下角的b點。在走過的路上,他可以取走方格中的數(取走後的方格中將變為數字0)。
此人從a點到b 點共走兩次,試找出2條這樣的路徑,使得取得的數之和為最大。
輸入描述 input description
輸入的第一行為乙個整數n(表示n*n的方格圖),接下來的每行有三個整數,前兩個表示位置,第三個數為該位置上所放的數。一行單獨的0表示輸入結束。
輸出描述 output description
只需輸出乙個整數,表示2條路徑上取得的最大的和。
樣例輸入 sample input
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0
樣例輸出 sample output
資料範圍及提示 data size & hint
如描述
題目直接限制了只能向下或向右走,換句話說就是每個點只能由上或由左走到。因此,如果只考慮一條路徑,還是比較直觀就能想明白:
設f[i][j]表示走到i行j列時的最大值
則f[i][j]=max +a[i][j]//f[i][j]只能由這兩格轉移來
只考慮一條路徑就可以這麼寫:
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(f[i-1][j]>f[i][j-1])f[i][j]=f[i-1][j]+map[i][j];
else f[i][j]=f[i][j-1]+map[i][j];
雖然,題目要求又多了一條路徑,但是如果沿著這個思路,也就不難想了,只是需要四維陣列,分別記下兩條路徑。而下乙個狀態,應該是以四種狀態中的最大值轉移得來。由於題目限制n<=10,於是就可以不用猶豫使用這樣的四種迴圈動規求解了,列出動態轉移方程
: 設f[i][j][k][l]表示第一條路徑走到i行j列,第二條路徑走到k行l列時的最大值
則f[i][j][k][l]=max+a[i][j]+a[k][l]
//分別是第一條路徑的兩種和第二條路徑的兩種,乘法原理
因此,最後的寫法就是個四重迴圈o(n^4)//n<=10
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
for(k=1;k<=n;k++)
for(l=1;l<=n;l++)
這裡還有乙個容易忽視的細節,i,j,k,l重合時,a[i][j]只能被加一次//邊界條件
這題儘管不是很難理解,但利用了n<=10這一條件,用四維陣列dp的做法還是很巧妙。
居然還有四維壓三維的做法
之前的f[i][j][k][l]四維做法,會發現有許多冗餘計算:對於每一組路徑上各取一點的所有組合都會被重複計算。
我們可以發現因為只能向下或向右,兩條路徑的長度是確定的,而設共走了k步(以左上角為第一步),對於每乙個k,點(i,j)的座標都有i=k-j+1,因此就可以以乙個k代替原來的兩個橫座標(或縱座標)。
於是可以進行三維的優化:
設f[i][j][k]表示第一條路徑走到第i列,第二條路徑走到第j列,共走了k步時的最大值
這樣,動態轉移方程就是:
f[i][j][k]=max(f[i-1][j][k-1],f[i][j-1][k-1],f[i][j][k-1],f[i-1][j-1][k-1])+a[i][k-i+1]+a[j][k-j+1]
//f[i][j][k]由上一步k-1的四個點的最大值轉移,四個點與四維做法相同
還有一點是,由於記錄的是步數,對應步數下的i,j取值範圍改變,應為[1,k](k<=n),[k-n+1,n](k>n)
所以,最後的**o(n^3):
f[1][1][1]=map[1][1];
for(k=2;k<=2*n-1;k++)
for(i=max(1,k-n+1);i<=min(n,k);i++)
for(j=max(1,k-n+1);j<=min(n,k);j++)
printf("%d",f[n][n][2*n-1]);
這就很妙了( ̄▽ ̄)~* NOIp2000 方格取數
設有n n的方格圖 n 10,我們將其中的某些方格中填入正整數,而其他的方格中則放入數字0。如下圖所示 見樣例 某人從圖的左上角的a 點出發,可以向下行走,也可以向右走,直到到達右下角的b點。在走過的路上,他可以取走方格中的數 取走後的方格中將變為數字0 此人從a點到b 點共走兩次,試找出2條這樣的...
NOIP2000 方格取數
時間限制 1 sec 記憶體限制 64 mb 設有n n的方格圖,我們將其中的某些方格中填入正整數,而其他的方格中則放入數字0。如下圖所示 見樣例 在走過的路上,他可以取走方格中的數 取走後的方格中將變為數字0 此人從a點到b 點共走兩次,試找出2條這樣的路徑,使得取得的數之和為最大。第1行 1個整...
NOIP2000方格取數 DP
設有n n的方格圖 n 9 我們將其中的某些方格中填入正整數,而其他的方格中則放 人數字0。如下圖所示 見樣例 a 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 14 0 0 0 0 0 21 0 0 0 4 0 0 0 0 15 0 ...