貪心與動態規劃相同點是要求原問題必須有最優子結構。而不同點在於貪心法的計算方式為 Top down,並不等待子問題求解完畢後再選擇使用哪一個,而是通過一種策略直接選擇一個子問題去求解,沒被選擇的子問題直接拋棄。這種所謂「最優選擇」的正確性需要用歸納法證明。而動態規劃不管是採用自 top down 或 bottom up 的計算方式,都是從邊界開始向上得到目標問題的解(即考慮所有子問題)。
#include<bits/stdc++.h>#define int long longusingnamespacestd;usingpii=pair<int,int>;constintMAXN=50010;intn,k,m;intp[MAXN],c[MAXN];boolbuy[MAXN];// buy[i] 表示第 i 個物品是否被買過intans=0;priority_queue<pii,vector<pii>,greater<pii>>P,C;priority_queue<int,vector<int>,greater<int>>delta;signedmain(){cin>>n>>k>>m;for(inti=1;i<=n;++i){cin>>p[i]>>c[i];P.push(make_pair(p[i],i));C.push(make_pair(c[i],i));}for(inti=1;i<=k;++i){delta.push(0);}while(!P.empty()){auto[pval,pid]=P.top();auto[cval,cid]=C.top();if(buy[pid]){// 如果被買過了,就跳過P.pop();continue;}if(buy[cid]){C.pop();continue;}if(delta.top()+cval>pval){// 用原價買 i 比較划算m-=pval;P.pop();buy[pid]=true;}else{// 否則的話,就是用優惠券買 i 比較划算m-=cval+delta.top();delta.pop();C.pop();buy[cid]=true;delta.push(p[cid]-c[cid]);}if(m>=0){ans++;}else{break;}}cout<<ans<<endl;return0;}
#include<bits/stdc++.h>#define F first#define S second#define int long longusingnamespacestd;usingpii=pair<int,int>;signedmain(){strings;cin>>s;intn=s.size();priority_queue<pii,vector<pii>,greater<pii>>pq;intl=0,ans=0;for(inti=0;i<n;i++){if(s[i]=='('){l++;continue;}else{if(s[i]=='?'){inta,b;cin>>a>>b;pq.push({a-b,i});s[i]=')';ans+=b;}if(--l<0){if(pq.empty()){cout<<"-1"<<'\n';exit(0);}ans+=pq.top().F;s[pq.top().S]='(';l+=2;pq.pop();}}}if(l){cout<<"-1"<<'\n';exit(0);}cout<<ans<<'\n'<<s<<'\n';}
#include<bits/stdc++.h>#define int long longusingnamespacestd;voidsolve(){intk;cin>>k;strings;cin>>s;intn=s.size();priority_queue<int>pq;vector<int>stk;intcost=0;for(inti=n-1;i>=0;i--){if(s[i]=='('){cost+=stk.back()-i-1;pq.push(stk.back()-i-1);stk.pop_back();}else{stk.push_back(i);}}while(pq.size()){if(k==0)break;k--;cost-=pq.top();pq.pop();}cout<<cost/2<<'\n';}signedmain(){intt;cin>>t;while(t--){solve();}}
#include<bits/stdc++.h>#define int long longusingnamespacestd;constintN=2e5+5;intl[N],r[N],n,k;voidsolve(){priority_queue<int,vector<int>,greater<int>>q;cin>>n>>k;for(inti=1;i<=n;i++){cin>>l[i];}for(inti=1;i<=n;i++){cin>>r[i];}intnum=0,sum=0,ans=INT_MAX;for(inti=1;i<=n;i++){q.push(r[i]-l[i]+1);num++;sum+=r[i]-l[i]+1;while(q.size()&&sum>=k){ans=min(ans,r[i]-(sum-k)+num*2);sum-=q.top();q.pop();num--;}}if(ans==INT_MAX){cout<<"-1\n";return;}else{cout<<ans<<'\n';}}signedmain(){intt;cin>>t;while(t--){solve();}}
#include<bits/stdc++.h>#define int long longusingnamespacestd;usingpii=pair<int,int>;structInterval{intl,r,id;booloperator<(constInterval&rhs)const{returnl<rhs.l;}};constintINF=9e18;constintMAXN=2e5+5;intn,k,ans[MAXN];signedmain(){cin>>n;vector<Interval>a(n);for(inti=0;i<n;i++){cin>>a[i].l>>a[i].r;a[i].id=i;}sort(a.begin(),a.end());priority_queue<pii,vector<pii>,greater<pii>>pq;pq.push({a[0].r,1});ans[a[0].id]=1;intcnt=1;for(inti=1;i<n;i++){auto[t,room]=pq.top();if(t<a[i].l){pq.pop();pq.push({a[i].r,room});ans[a[i].id]=room;}else{pq.push({a[i].r,++cnt});ans[a[i].id]=cnt;}}cout<<cnt<<'\n';for(inti=0;i<n;i++){cout<<ans[i]<<" ";}}
#include<bits/stdc++.h>#define int long longusingnamespacestd;intn,ans;inta[300010],b[300010];boolvis[300010];priority_queue<pair<int,int>,vector<pair<int,int>>>q;// 维护一个大根堆signedmain(){scanf("%lld",&n);intrest=0;for(inti=1;i<=n;i++)scanf("%lld",&a[i]);for(inti=1;i<=n;i++)scanf("%lld",&b[i]);for(inti=1;i<=n;i++){rest+=a[i];if(b[i]<=rest){ans++;q.push(make_pair(b[i],i));rest-=b[i];vis[i]=1;}elseif(!q.empty()&&b[i]<q.top().first){intj=q.top().second;q.pop();rest+=b[j];rest-=b[i];vis[j]=0,vis[i]=1;q.push(make_pair(b[i],i));}}printf("%lld\n",ans);for(inti=1;i<=n;i++)if(vis[i])printf("%d ",i);return0;}
#include<bits/stdc++.h>#define int long longusingnamespacestd;constintN=1e5+5;intv[N],a[N],b[N];priority_queue<int,vector<int>,greater<int>>pq1,pq2;signedmain(){intn,x,y,z;cin>>n>>x>>y>>z;intans=0;for(inti=1;i<=n;i++){cin>>a[i]>>b[i];for(intj=1;j<=a[i]-b[i];j++){v[i]=y;if(!pq1.empty()){v[i]=min(v[i],i*z+pq1.top());pq1.pop();}pq2.push(-v[i]-i*z);ans+=v[i];}for(intj=1;j<=b[i]-a[i];j++){v[i]=x;if(!pq2.empty()){v[i]=min(v[i],i*z+pq2.top());pq2.pop();}pq1.push(-v[i]-i*z);ans+=v[i];}}cout<<ans<<'\n';}
#include<bits/stdc++.h>usingnamespacestd;#define N 100005#define ll long long#define INF 2000000000intn,m;llX[N];llY[N],W[N],C[N];llans;structinfo{llv,cnt;};booloperator<(infoa,infob){returnb.v<a.v;}priority_queue<info>q0,q1;voidins0(llx){infot=q1.top();q1.pop();ans+=x+t.v;if(--t.cnt)q1.push(t);q0.push((info){-(x+t.v)-x,1});}voidins1(llx,llcost,llc){lls=0;while(c&&!q0.empty()){infot=q0.top();if(cost+x+t.v>=0)break;q0.pop();llmn=min(t.cnt,c);ans+=(cost+x+t.v)*mn;q1.push((info){-(cost+x+t.v)-x+cost,mn});s+=mn;t.cnt-=mn;c-=mn;if(t.cnt)q0.push(t);}if(c)q1.push((info){-x+cost,c});if(s)q0.push((info){-cost-x,s});}intmain(){scanf("%d%d",&n,&m);for(inti=1;i<=n;++i)scanf("%lld",&X[i]);llsum=0;for(inti=1;i<=m;++i)scanf("%lld%lld%lld",&Y[i],&W[i],&C[i]),sum+=C[i];if(sum<n){printf("-1\n");return0;}q1.push((info){INF,INF});inti=1,j=1;while(i<=n||j<=m)// 保证老鼠和窝的相对位置if(i<=n&&(j>m||X[i]<Y[j]))ins0(X[i]),i++;elseins1(Y[j],W[j],C[j]),j++;printf("%lld\n",ans);return0;}