二維的dp非常顯然,但這也沒有什麼優化的餘地了。
注意到最後的方案中只有產生貢獻的位置是有用的,剩下的部分可以在該範圍內任意選取。
所以我們考慮設f[i]為i號位最後產生貢獻的答案,則f[i]=max (i-j>=a[i]-a[j],a[i]>a[j])。
觀察這個限制,即為i-a[i]>=j-a[j]且a[i]>a[j],以及i>j。可以發現這裡i>j的限制是可以被前兩個限制所包含的。於是我們考慮換個順序dp,按照a[i]從小到大來。樹狀陣列維護即可。
至於刪數數量,只需要保證i-a[i]<=k<=n-a[i]。
#include#include#include
#include
#include
#include
using
namespace
std;
intread()
while (c>='
0'&&c<='
9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}#define n 1000010
intn,m,tree[n];
struct
data
}a[n];
void ins(int k,int x)
int query(int k)
intmain()
while (i<=t)
}for (int i=1;i<=n;i++)
if (a[i].i-a[i].x<=m&&m<=n-a[i].x) a[0].ans=max(a[0
].ans,a[i].ans);
cout
<0
].ans;
return0;
}
46 動態規劃 機器更新問題
import random as rd from pyscipopt import model,quicksum def c generate n,dc c 0 for i in range n for i in range n 1 c i 1 c i int rd.random dc return...
動態規劃 數塔
如圖所示為乙個數塔,從頂部出發在每乙個節點可以選擇向左走或向右走,一直走到最底層,要求找出一條路徑,使路徑上的數值和最大。include define n 50 int data n n d n n 定義陣列data,d int n void operate for i n 1 i 1 i else...
動態規劃 塔數
有如下所示的數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少?輸入資料首先包括乙個整數c,表示測試例項的個數,每個測試例項的第一行是乙個整數n 1 n 100 表示數塔的高度,接下來用n行數字表示數塔,其中第i行有個i個整數,且所有的整數均在區間 0,99 內。...