區間dp模版:
for (int len = 1; len < n; len++)
}}
如果我們要得知乙個大區間的情況,由於它必定是由從多個長度不一的小區間轉移而來**移情況未知),我們可以通過求得多個小區間的情況,從而合併資訊,得到大區間。這樣的演算法複雜度為o(n^3)。
例:石子合併問題
#include #define min(x, y) (x > y ? y : x)
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 210;
int dp[maxn][maxn];
int sum[maxn];
int a[maxn];
int main(int argc, const char * argv)
for (int len = 1; len < n; len++) }}
printf("%d\n", dp[1][n]);
}return 0;
}
題目總結:
平形四邊形優化分析:
在動態規劃中,經常遇到形如下式的狀態轉移方程:
m(i,j)=min+w(i,j)(i≤k≤j)(min也可以改為max)
上述的m(i,j)表示區間[i,j]上的某個最優值。w(i,j)表示在轉移時需要額外付出的代價。該方程的時間複雜度為o(n3)
下面我們通過四邊形不等式來優化上述方程,首先介紹什麼是「區間包含的單調性」和「四邊形不等式」
1、區間包含的單調性:如果對於 i≤i'2、四邊形不等式:如果對於 i≤i'
下面給出兩個定理:
1、如果上述的 w 函式同時滿足區間包含單調性和四邊形不等式性質,那麼函式 m 也滿足四邊形不等式性質
我們再定義 s(i,j) 表示 m(i,j) 取得最優值時對應的下標k(即 i≤k≤j 時,k 處的 w 值最大,則 s(i,j)=k)。此時有如下定理
2、假如 m(i,j) 滿足四邊形不等式,那麼 s(i,j) 單調,即 s(i,j)≤s(i,j+1)≤s(i+1,j+1)。
好了,有了上述的兩個定理後,我們發現如果w函式滿足區間包含單調性和四邊形不等式性質,那麼有 s(i,j-1)≤s(i,j)≤s(i+1,j) 。
即原來的狀態轉移方程可以改寫為下式:
m(i,j)=min+w(i,j)(s(i,j-1)≤k≤s(i+1,j))(min也可以改為max)
由於這個狀態轉移方程列舉的是區間長度 l=j-i,而 s(i,j-1) 和 s(i+1,j) 的長度為 l-1,是之前已經計算過的,可以直接呼叫。
不僅如此,區間的長度最多有n個,對於固定的長度 l,不同的狀態也有 n 個,故時間複雜度為 o(n^2),而原來的時間複雜度為 o(n^3),實現了優化!
今後只需要根據方程的形式以及 w 函式是否滿足兩條性質即可考慮使用四邊形不等式來優化了。
例:石子合併
#include #include #define n 1005
int s[n][n],f[n][n],sum[n],n;
int main()
for(int i=1; i<=n; i++)
f[i][i+1]=sum[i+1]-sum[i-1];
for(int i=n-2; i>=1; i--)
for(int j=i+2; j<=n; j++)
for(int k=s[i][j-1]; k<=s[i+1][j]; k++)
if(f[i][j]>f[i][k]+f[k+1][j]+sum[j]-sum[i-1])
printf("%d\n",f[1][n]);
}return 0;
}
平行四邊形
請小夥伴們對自己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 每組資...
平行四邊形數
c 平行四邊形數 time limit 2000ms memory limit 32768kb 64bit io format i64d i64u fzu 2231 description 在乙個平面內給定n個點,任意三個點不在同一條直線上,用這些點可以構成多少個平行四邊形?乙個點可以同時屬於多個平...