首先先看一下不環形的題目:石子合併
直接附上**,思路很簡單,從小區間求出大區間,手打的很快,樣例也很弱,應該沒什麼問題:
#include
using
namespace std;
const
int maxn =
305;
int dp[maxn]
[maxn]
;int sum[maxn]
, arr[maxn]
;int
main()
}}cout << dp[0]
[n -1]
;}
現在來分析一下環形的:
環形石子:
其實這道題在網上真是一搜一大堆,但是所有的文章上來都是,從1-n新增到1-2*n計算,沒有任何的文章有解釋過,所以這裡來分析一下,並且大部分的環形題目都差不多。
這裡紅色的是起點(逆時針),也就是索引0的位置,從左往右,到最後將n個合併在一起的時候,有這幾種情況:
for
(int k =
0; k <
7; k++
) dp[0]
[7]=
min(dp[i]
[j],dp[i]
[k]+ dp[k +1]
[j]+ sum[j +1]
- sum[i]
);
但是沒有考慮到比如1-2和3-0合併呢,或者3-5和6-2合併呢(逆時針),所以當我們把1-n的陣列延伸到1-2n,看下圖,這樣當我們求dp[0][7]就包括了以a0為首所有的情況,而上面的1-2和3-0合併就可以在dp[1][8]中有,3-5和6-2合併就在dp[3][10]中體現,所以這就是伸展到1-2n的原因
下面來分析一下平行四邊形不等式優化,在下面這個部落格裡是我看的最懂的了分析,而我就單單來分析一下這題的證明:
其實就是證明a<=b<=c<=d,w[a,c] + w[b,d] <= w[a,d] + w[b,c]
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j]) + sum[j + 1] - sum[i])
首先要先證明sum符合:sum[a,c] + sum[b,d] = sum[a,d] + sum[b,c],符合
接下來證明dp符合:
dp[a, c] + dp[b, d]
dp[a, d] + dp[b, c]
= dp[a,b] + dp[b,d] + sum[a,d] + dp[b,c]
=dp[a,b] + dp[b,c] + sum[a,c] + sum[c,d] + dp[b,d]
=dp[a,c] + dp[b,d] + sum[c,d] > dp[a, c] + dp[b, d]
證明完畢。
最後貼一下ac**:
#include
using
namespace std;
const
int inf =
1e9+7;
const
int maxn =
(1005
)<<1;
int arr[maxn]
, dp[maxn]
[maxn]
;int sum[maxn]
, s[maxn]
[maxn]
;int
solve
(int n)}}
int ans = inf;
for(
int i =
0; i < n; i++
)return ans;
}int
main()
return0;
}
平行四邊形
請小夥伴們對自己ac的題目進行標記,注意每人只能標記一次!不知道的不要標記,惡意標記者將 賬號!時間限制 3 sec 記憶體限制 128 mb 提交 狀態 題目描述 求平面上n個點構成的平行四邊形個數。輸入 一行乙個數n。接下來n行,每行兩個數x,y,表示這個點的座標為 x,y 保證任意兩點不重合,...
平行四邊形邊數
在乙個平面內給定n個點,任意三個點不在同一條直線上,用這些點可以構成多少個平行四邊形?乙個點可以同時屬於多個平行四邊形。input 多組資料 10 處理到eof。每組資料第一行乙個整數n 4 n 500 接下來n行每行兩個整數xi,yi 0 xi,yi 1e9 表示每個點的座標。output 每組資...
區間DP 平行四邊形優化分析
區間dp模版 for int len 1 len n len 如果我們要得知乙個大區間的情況,由於它必定是由從多個長度不一的小區間轉移而來 移情況未知 我們可以通過求得多個小區間的情況,從而合併資訊,得到大區間。這樣的演算法複雜度為o n 3 例 石子合併問題 include define min ...