part1.30pts
顯然,前30分是很好寫的。
\(dp[i][j]\)表示前i個箱子分成了j個組的最小代價。
複雜度:\(o(n^3)\)
**:
namespace p30}}
for(int i=1;i<=n;i++)ans=min(ans,dp[n][i]);
cout對於這部分費用:
對於第i個箱子,如果裡面裝的貨物總重量為w,那麼費用為i*w 。
我們轉化一下,假設有5個物品,編號為1,2,3,4,5。其中裝的箱子為,,。
那麼上述費用就是:\(a[1]\cdot 1+a[2]\cdot 1+a[3]\cdot2+a[4]\cdot3+a[5]\cdot3\),也可以寫成\((a[1]+a[2]+a[3]+a[4]+a[5])+(a[3]+a[4]+a[5])+(a[4]+a[5])\)。
這樣,當我們考慮到第i個物品時,不管第i+1個到第n個怎麼取,最終答案至少要多花費\(\sum_^a[j]\)。
因此,我們設\(dp[i]\)表示考慮前i個物品時,最終花費的最小總代價。
轉移方程:
\[dp[0]=\sum_^a[k]
\]\[dp[i]=min\+\sum_^a[k] j\in[0,i-1],\sum_^a[k]\le w
\]其中\(max(j+1,i)\)表示j+1到i中a的最大值,\(min(j+1,i)\)則表示最小值。
複雜度:\(o(n^2)\)
**:namespace p60
}cout對於\(max(j+1,i)\)和\(min(j+1,i)\)可以用單調棧維護。
由於\(max(j+1,i)\)和\(min(j+1,i)\)是不斷變化的,所以我們需要開一棵線段樹維護。
複雜度:\(o(n\cdot logn)\)
具體細節請看**吧。
**:namespace p100 tree[maxn<<2];
ll dp[maxn];
void down(int p)
void up(int p)
void build(int l,int r,int p)
int mid=(l+r)>>1;
build(l,mid,p<<1);
build(mid+1,r,p<<1|1);
up(p);
}void update1(int pos,int p,ll x)
down(p);
int mid=(tree[p].l+tree[p].r)>>1;
if(pos<=mid)update1(pos,p<<1,x);
else update1(pos,p<<1|1,x);
up(p);
}void update2(int l,int r,int p,int x)
down(p);
int mid=(tree[p].l+tree[p].r)>>1;
if(r<=mid)update2(l,r,p<<1,x);
else if(l>=mid+1)update2(l,r,p<<1|1,x);
else update2(l,mid,p<<1,x),update2(mid+1,r,p<<1|1,x);
up(p);
}ll query(int l,int r,int p)
void work()
update2(stkmx[topmx]+1,i,1,a[i]);//把現在的mx給加過去(更新)
stkmx[++topmx]=i;
int l=0,r=i-1,res;
while(l<=r)
dp[i]=0ll+query(res+1,i,1)+sum[n]-sum[i];
update1(i+1,1,dp[i]);
}cout<}
}
牛客網 身份證分組
18位身份證的編碼規則是 前1 2位數字表示 所在省 直轄市 自治區 的 第3 4位數字表示 所在地級市 自治州 的 第5 6位數字表示 所在區 縣 自治縣 縣級市 的 第7 14位數字表示 出生年 月 日 第15 16位數字表示 所在地的派出所的 第17位數字表示性別 奇數表示男性,偶數表示女性 ...
牛客網 華為機試 020 牛客網
密碼要求 1.長度超過8位 2.包括大小寫字母.數字.其它符號,以上四種至少三種 3.不能有相同長度超2的子串重複 說明 長度超過2的子串 一組或多組長度超過2的子符串。每組佔一行 如果符合要求輸出 ok,否則輸出ng 示例1 021abc9000 021abc9abc1 021abc9000 02...
牛客網 乳酪
題目很簡單,中文題。複製了 乳酪之間距離不用管,只要開個並查集維護就好了,另外需要選好幾個點作為起點幾個點作為終點。o n 2 的建圖。感覺可以平面掃瞄。有空去試試。以下 ac includeusing namespace std const int maxn 1e5 5 define ll lon...