多邊形 區間dp

2022-02-02 01:35:27 字數 1526 閱讀 2158

題意簡單來說就是:給你乙個環,斷掉一條邊使其成為乙個鏈,用這個鏈跑dp,求最大得分。

首先這不是一道板子題。。。跟板子區別如下:

1.多了一重迴圈,最開始要求斷掉一條邊,但是我們不知道要斷掉哪一條邊,因此需要迴圈一遍來比較。

2.計算方法有加法有乘法,而且資料有正數有負數。這兩個條件任意乙個都不足懼,但是如果湊在一起。。。就很微妙了。

何出此言?比如說,我們用 f [ i ] [ j ]來表示從i號點到j號點的最大得分。那麼假如,最後一次的運算是乘法。你在最後一次計算的時候,用於相乘的兩個數,肯定都是它們各自那個區間的最優解,也就是最大的。然而,假如說在這個過程中,你淘汰了一些負數的值,那就很危險了。比如,你最後選擇了1000和100相乘,但是本來你可以讓-10000和-3000相乘的,那不就直接gg了嗎。。

負負得正,真是麻煩。。。。

那怎麼解決呢?其實也簡單。只要另開乙個陣列記錄最小得分即可~~;

3.題目還要求: 有些邊如果在首次移動中被刪除,可以導致最高得分。在輸出檔案的第二行,要求列舉出所有這樣的邊,而且按照公升序輸出,其間用乙個空格分開。(這句話直接貼上的),也就是說,我們需要用乙個陣列把每條邊和斷掉該條邊所能獲得的最大得分匹配起來,以便最後比較。

說的差不多了,上**:

1 #include 2 #include 3 #include 4 #include 5 #include 6

using

namespace

std;

7const

int maxn=50+5,inf=1e9+10;8

int n,data[maxn<<1];//

用來儲存各點權;因為是環,所以左移一位;

9int f[maxn<<1][maxn<<1][3];//

f[i][j][1]表示從i號點到j號點的最大得分,f[i][j][2]表示從***到***的最小得分;

10int ff[maxn<<1];//

ff儲存每條斷邊的最大得分,便於最後查詢 ;

11char c[maxn<<1]; //

儲存符號;

12int q,w,e,r;//

方便比較的變數。。

13int ans_point=(-1)*inf;//

最大得分,先初始化為最小;

14void

read()21}

22void

solve()29}

30for(int j=1;j<=(n<<1);++j)

35for(int l=2;l<=n;++l)else50}

51}52}

53 ff[i]=f[i][i+n-1][1];//

注意是i+n-1不是i+n。。小學學的植樹問題不要搞錯; 54}

55for(int i=1;i<=n;++i)

58 printf("

%d\n

",ans_point);//

注意換行;

59for(int i=1;i<=n;++i)62}

63int main()

區間DP 凸多邊形的劃分

這道題確實想了很久。關鍵我不知道這個last點怎麼找。接下來講講我的過程吧。1,集合 n 2條邊組成的凸多邊形的答案。因為劃分的時候我們是按照三角形來進行劃分的所以我們可以理解為,我們的last點其實是乙個三角形,那麼我們凸邊形的權值就是兩個小凸邊形加乙個三角形的權值 2,屬性 最小值。3,狀態 l...

Hzoi 2018 2 11多邊形 區間DP

給 定乙個由n個頂點構成的多邊形,每個頂點被賦予乙個整數值,而每條邊則被賦予乙個符號 加法運算 或者 乘法運算 所有邊依次用整數1到n標識。乙個多邊形的圖形表示 首次移動,允許將某條邊刪除 接下來的每次順序移 動包括下面步驟 1 選出一條邊e,以及由e聯接的頂點v1和v2 2 用乙個新的頂點,取代邊...

多邊形遊戲(DP)

多邊形遊戲是乙個單人玩的遊戲,開始時有乙個由n個頂點構成的多邊形。每個頂點被賦予乙個整數值,每條邊被賦予乙個運算子 或 所有邊依次用整數從1到n編號。遊戲第1步,將一條邊刪除。隨後的n 1步按以下方式操作 1 選擇一條邊e以及由e連線著的兩個頂點v1和v2 2 用乙個新的頂點取代邊e以及由e連線著的...