遙遠的金字塔
題目背景:
10.27 noip
模擬t2
分析:斜率優化dp
講道理,
noip
這麼考真的好嗎,而且我特喵很想知道啊,為毛能夠把我的正解卡
t啊,我真的是非常不爽啊,喵喵喵喵喵
講題。首先,我們可以知道,如果因為這一行是嚴格小於上一行的,並且我們稍微用腦袋想想就知道,最優的方式一定是,選擇連續很多條,然後寬度就是最窄的那一條就好了,那麼我們就可以考慮用
dp來做了。定義
dp[i][c]
表示,目前在第
i行,已經選擇了
c個矩形的最優解,那麼轉移顯然就是
dp[i][c] = dp[j][c - 1] + (i - j) * l[i](l[j]
表示,j
的寬度)
,那麼這樣呢,我們就已經有了乙個
o(n2k)
的演算法了,顯然過不去·····考慮如何優化,我們來推推式子,如果對於兩個
dp[j][c - 1]
和dp[k][c - 1]
,j > k
,如果從
j轉移更優秀的話,滿足
dp[j][c - 1] + i * l[i] - j * l[i] > dp[k][c - 1] + i * l[i] - k *l[i] ð
dp[j][c - 1] - dp[k][c - 1] > (j - k)l[i] ð
(dp[j][c - 1] - dp[k][c - 1]) / (j - k) > l[i]
也就是說當滿足上面的不等式時,j比
k作為決策更加優,那麼我們定義上面的額
s(k, j) = (dp[j][c - 1] - dp[k][c - 1]) / (j - k),
那麼如果存在三個決策滿足
, s(k, j) ,那麼
j一定是沒有意義的決策,因為,如果
s(k, j) < l[i]
,那麼顯然k比
j優,如果
s(k, j) > l[i],
那麼s(j, x) > l[i]
,那麼x
又一定比
j優,所以我們只需要維護乙個雙端佇列,每次加入新決策前,先將倒數兩個決策和新的決策比較,將不夠優秀的決策扔出去,而每一次需要選擇
i的決策時,將前面所有
s(k, j) > l[i]的k
彈出,最後留在隊首的就是
i的決策,這樣複雜度就被優化成
o(nk)
啦,然後這就是標算複雜度了。
source:
/*
created by scarlyw
*/#include #include #include #include #include #include #include #include #include #include inline char read()
return *s++;
}templateinline void r(t &x)
for (x = 0; isdigit(c); c = read())
x = ((x << 2) + x << 1) + (c ^ '0');
if (iosig) x = -x;
}const int out_len = 1024 * 1024;
char obuf[out_len], *oh = obuf;
inline void write_char(char c)
templateinline void w(t x)
}inline void flush()
/*templateinline void r(t &x)
for (x = 0; isdigit(c); c = getchar())
x = ((x << 2) + x << 1) + (c ^ '0');
if (iosig) x = -x;
}//*/
const int maxn = 20000 + 10;
const int maxk = 100 + 10;
int n, k, x, y;
long long dp[maxn], f[maxn];
int l[maxn];
inline void read_in()
inline double calc(int k, int j)
inline void solve()
for (int i = 1; i <= n; ++i) dp[i] = f[i];
} long long ans = 0;
for (int i = 1; i <= n; ++i) ans = std::max(ans, f[i]);
std::cout << ans;
}int main()
NOIP模擬(20171024)T2 乘積
求從1 n中選k個數,使得這k個數的乘積不含完全平方因子 70 n 30 100 n 500 狀壓dp,f i j k 表示前i個數,選了j個,當前所選數之積分解質因數後的狀態為k k表示成二進位制後,第一位表示有沒有2,第二位表示有沒有3 以此類推 令i 1分解質因數後狀態為po s i 1 f ...
NOIP 模擬題 T2 寶藏(樹形dp)
題解 樹形dp 其實這道題說起來很簡單,用四個陣列 d1 d0 u0 u1分別表示從當前點向下更新,不返回 從當前點向下更新再回到當前點 從當前點向上更新回到當前點 從當前點向上更新不返回。用兩遍dfs求出這四個陣列 實現起來細節會比較多,耐心處理 include include include d...
NOIP模擬(11 03)T2 排列
排列 題目背景 11.03 noip 模擬t2 分析 線段樹 唯一一道可做題 我們從n 1 來確定每個數的位置,顯然,我們放入 n的時候,他一定在乙個逆序對數為 0的位置,因為它的前面不可能有比它大的,其次,如果 0位有多個,它一定在最後乙個 0位上,因為如果在前面的 0位上,後面的 0位上的數字一...