日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【DP】树塔狂想曲

發布時間:2023/12/3 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【DP】树塔狂想曲 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

樹塔狂想曲

題目大意:

有一個數字金字塔,讓你求出去掉一個點后,從最頂端走到最低端的最大值(只能往下或右下走)

原題:

題目描述

相信大家都在長訓班學過樹塔問題,題目很簡單求最大化一個三角形數塔從上往下走的路徑和。走的規則是:(i,j)號點只能走向(i+1,j)或者(i+1,j+1)。如下圖是一個數塔,映射到該數塔上行走的規則為:從左上角的點開始,向下走或向右下走直到最底層結束。

1
3 8
2 5 0
1 4 3 8
1 4 2 5 0

路徑最大和是1+8+5+4+4 = 22,1+8+5+3+5 = 22或者1+8+0+8+5 = 22。
小S覺得這個問題so easy。于是他提高了點難度,他每次ban掉一個點(即規定哪個點不能經過),然后詢問你不走該點的最大路徑和。
當然他上一個詢問被ban掉的點過一個詢問會恢復(即每次他在原圖的基礎上ban掉一個點,而不是永久化的修改)。

輸入

第一行包括兩個正整數,N,M,分別表示數塔的高和詢問次數。
以下N行,第i行包括用空格隔開的i - 1個數,描述一個高為N的數塔。
而后M行,每行包括兩個數X,Y,表示第X行第Y列的數塔上的點被小S ban掉,無法通行。
(由于讀入數據較大,c或c++請使用較為快速的讀入方式)

輸出

M行每行包括一個非負整數,表示在原圖的基礎上ban掉一個點后的最大路徑和,如果被ban掉后不存在任意一條路徑,則輸出-1。

輸入樣例

5 3 1 3 8 2 5 0 1 4 3 8 1 4 2 5 0 2 2 5 4 1 1

輸出樣例

17 22 -1

說明

【樣例解釋】

第一次是

1 3 X 2 5 0 1 4 3 8 1 4 2 5 0

1+3+5+4+4 = 17 或者 1+3+5+3+5=17
第二次:

1 3 8 2 5 0 1 4 3 8 1 4 2 X 0

1+8+5+4+4 = 22
第三次:你們都懂的!無法通行,-1!

解題思路:

很明顯, 直接暴力是不可能的,我們先預處理出來從起點到某個點的最大值,和從某個點到終點的最大值,然后就可以求出經過某個點的最大值,然后就可以求出某一行的最大值和次大值
然后入過經過輸入的點是最大值,那說明不能走,那走次大的,否則走最大的

代碼:

#include<cstdio> #include<cstring> #include<iostream> using namespace std; int n,m,xx,yy,num,a[1005][1005],f[1005][1005]; int df[1005][1005],ff[1005][1005],ans[1005],ans1[1005]; int read()//快讀 {char x=getchar();int d=1,l=0;while (x<'0'||x>'9') {if (x=='-') d=-1;x=getchar();}while (x>='0'&&x<='9') l=(l<<3)+(l<<1)+x-48,x=getchar();return l*d; } void writ(int c) {if (c>9) writ(c/10); putchar(c%10+48); return;} void write(int s) {s<0?putchar(45),writ(-s):writ(s); putchar(10); return;} int main() {n=read();m=read();for (int i=1;i<=n;++i)for (int j=1;j<=i;++j){a[i][j]=read();f[i][j]=max(f[i-1][j],f[i-1][j-1])+a[i][j];//預處理}for (int i=n;i>0;--i)for (int j=1;j<=i;++j)df[i][j]=max(df[i+1][j],df[i+1][j+1])+a[i][j];for (int i=1;i<=n;++i){for (int j=1;j<=i;++j){ff[i][j]=max(f[i-1][j],f[i-1][j-1])+max(df[i+1][j],df[i+1][j+1])+a[i][j];//計算if (ff[i][j]>ans[i]) ans[i]=ff[i][j],num=j;//求最大的}for (int j=1;j<=i;++j)if (j!=num)ans1[i]=max(ans1[i],ff[i][j]);//求次大的}for (int i=1;i<=m;++i){xx=read();yy=read();if (xx==1&&yy==1) putchar(45),putchar(49),putchar(10);//無法到達else if (ff[xx][yy]==ans[xx]) write(ans1[xx]);//次大else write(ans[xx]);//最大} }

總結

以上是生活随笔為你收集整理的【DP】树塔狂想曲的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。