日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

牛客练习赛79E-小G的数学难题【dp,单调队列】

發(fā)布時間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客练习赛79E-小G的数学难题【dp,单调队列】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

正題

題目鏈接:https://ac.nowcoder.com/acm/contest/11169/E


題目大意

給出nnn個三元組(ai,bi,ci)(a_i,b_i,c_i)(ai?,bi?,ci?)

要求選出一個集合SSS,要求
(∑i∈Sai)≤P,(∑i∈Sbi)≥P\left(\sum_{i\in S}a_i\right)\leq P,\left(\sum_{i\in S}b_i\right)\geq P(iS?ai?)P,(iS?bi?)P
且最小化∑i∈Sci\sum_{i\in S}c_iiS?ci?

1≤T≤5,1≤n≤1000,1≤P≤10000,1≤ai≤bi≤2×106,1≤ci≤2×1061\leq T\leq 5,1\leq n\leq 1000,1\leq P\leq 10000,1\leq a_i\leq b_i\leq 2\times 10^6,1\leq c_i\leq 2\times 10^61T5,1n1000,1P10000,1ai?bi?2×106,1ci?2×106


解題思路

暴力的思路是設(shè)fi,l,rf_{i,l,r}fi,l,r?表示到第iii個,aia_iai?的和為lllbib_ibi?的和為rrr時的最小值。

但是這個O(nP2)O(nP^2)O(nP2)的顯然不行,發(fā)現(xiàn)有一個ai≤bia_i\leq b_iai?bi?的性質(zhì)考慮怎么使用。

其實(shí)還要一個相關(guān)的性質(zhì)就是兩個的限制的PPP是相等的,雖然看起來比較廢話但確實(shí)是有用的。

一個十分巧妙的dpdpdp是設(shè)fi,jf_{i,j}fi,j?表示aia_iai?的和≤j\leq jjbib_ibi?的和≥j\geq jj。雖然這樣的限制不完全,但是這樣確實(shí)可以統(tǒng)計(jì)到最小答案且不會統(tǒng)計(jì)到更小答案。

轉(zhuǎn)移就是
fi,j=min{fi?1,j,fi?1,p+ci}(p∈[j?bi,j?ai])f_{i,j}=min\{f_{i-1,j},f_{i-1,p}+c_i\}(p\in[j-b_i,j-a_i])fi,j?=min{fi?1,j?,fi?1,p?+ci?}(p[j?bi?,j?ai?])

這樣每一層用單調(diào)隊(duì)列維護(hù)就可以了

時間復(fù)雜度O(TnP)O(TnP)O(TnP)


code

#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=1100; ll T,n,P,a[N],b[N],c[N],f[N][N*10],q[N*10]; signed main() {scanf("%lld",&T);while(T--){scanf("%lld%lld",&n,&P);for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);for(ll i=1;i<=n;i++)scanf("%lld",&b[i]);for(ll i=1;i<=n;i++)scanf("%lld",&c[i]);memset(f,0x3f,sizeof(f));f[0][0]=0;for(ll i=1;i<=n;i++){ll tail=0,head=1,z=-1;for(ll j=0;j<=P;j++){f[i][j]=f[i-1][j];ll l=j-b[i],r=j-a[i];while(z<r){z++;if(f[i-1][z]>=1e18)continue;while(head<=tail&&f[i-1][q[tail]]>f[i-1][z])tail--;q[++tail]=z;}while(head<=tail&&q[head]<l)head++;if(head<=tail)f[i][j]=min(f[i][j],f[i-1][q[head]]+c[i]);}}if(f[n][P]>=1e18)printf("IMPOSSIBLE!!!\n");else printf("%lld\n",f[n][P]); }return 0; }

總結(jié)

以上是生活随笔為你收集整理的牛客练习赛79E-小G的数学难题【dp,单调队列】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。