ZOJ 3905 Cake (貪心+簡單DP)
阿新 • • 發佈:2018-12-16
#include<bits/stdc++.h> using namespace std; #define debug puts("YES"); #define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++) #define ll long long #define lrt int l,int r,int rt #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define root l,r,rt const int maxn =805; const int mod=1e9+7; const int ub=1e6; ll powmod(ll x,ll y){ll t; for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod; return t;} ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} /* 題目大意:意思是說 一個人帶來n塊蛋糕, 然後兩個人都對每塊蛋糕有自己的估值, 分配的方式是這樣,A每次拿出兩塊, 然後B拿走他認為大的那個,, 比如兩塊蛋糕, 1 2(第一塊) 3 4(第二塊) 那麼B拿走第二塊。 這樣我們先貪心排序, 按B從大到小排, 這樣就可以在A的維度上進行DP了。 這次DP有啥限制呢,只要保證當前所能選擇的集合 權值最大就行了。 那麼簡單思考下,偶數時候肯定是必選, 奇數時候,,把當前位數和之前選擇好的最小值交換, 那麼就涉及到維護動態最小值的問題,資料結構丟一下就行。 當然也可以網上做法,,,二維迴圈 暴力揹包一波。 複雜度:O(nlogn)。 */ struct node { int a,b; bool operator<(const node& y) const { return b>y.b; } }q[maxn]; int n; ll dp[maxn]; int main() { int t;scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&q[i].a,&q[i].b); sort(q+1,q+n+1); dp[1]=0;s.clear(); for(int i=2;i<=n;i++) { if(i%2==1)///選奇數 { if((*s.begin())<q[i].a) { dp[i]=dp[i-1]+q[i].a-(*s.begin()); s.erase(s.begin()); s.insert(q[i].a); } else dp[i]=dp[i-1]; } else { dp[i]=dp[i-1]+1LL*q[i].a; s.insert(q[i].a); } } printf("%lld\n",dp[n]); } return 0; }