題目傳送門
嘗試了一下弱化條件想題的方法,還不錯?
題目中有三種硬幣,並不利於直接貪心.我們不妨先考慮只有兩種硬幣的情況.按照貪心的思想,應該按照兩種硬幣的差值(即乙個人金幣的個數減去銀幣的個數)進行排序,然後從前選y個,剩下的x個都為金幣.
然後我們將條件加回來,發現性質有了一點點變化.因為有銅幣的影響,所以並不能直接選取y個這樣做.但是我們還是可以發現,從前開始選銀幣,和從後開始選金幣的區間是不會相重疊的.因為如果重疊,那麼兩個交換一下顯然更加優秀.所以我們列舉銀幣從[1,k]選取y個,金幣從[k+1,n]中選取x個.剩下的都為銅幣的情況下的最優解.這個東西用個map維護一下就好了
注意在實現的過程中要避免銅幣,對答案產生的影響,所以我們可以將金銀兩種硬幣的數量分別減去銅幣的數量,最後在同一加回來.就正好不會多,也不會漏.
#include
#include
#include
using namespace std;
typedef
long
long ll;
typedef pair pll;
const
int maxn=
1e5+5;
const ll inf=
1e18
;ll zsum,sum,ans=
-inf;
ll ans1[maxn]
,ans2[maxn]
;int x,y,z;
pll a[maxn]
;mapint> cnt;
bool cmp
(pll p,pll q)
intmain()
sort
(a+1
,a+n+
1,cmp)
;int st,ed;
sum=0;
for(st=
1;st<=y;st++
) ans1[y]
=sum;
for(
;st<=n-x;st++
) sum-
=cnt.
begin()
->first;
if(cnt.
begin()
->second>
1) cnt.
begin()
->second--
;else cnt.
erase
(cnt.
begin()
);cnt[a[st]
.second]++;
sum+
=a[st]
.second;
ans1[st]
=sum;
} cnt.
clear()
; sum=0;
for(ed=n;ed>n-x;ed--
) ans2[n-x+1]
=sum;
for(
;ed>=y;ed--
) sum-
=cnt.
begin()
->first;
if(cnt.
begin()
->second>
1) cnt.
begin()
->second--
;else cnt.
erase
(cnt.
begin()
);cnt[a[ed]
.first]++;
sum+
=a[ed]
.first;
ans2[ed]
=sum;
}for
(int i=y;i<=n-x;i++
) ans=
max(ans,ans1[i]
+ans2[i+1]
);printf
("%lld"
,ans+zsum)
;}
AGC 018C Coins 貪心 排序
題意 n個人 n x y z 每個人有金銀銅三種顏色硬幣a i b i c i 個,問向x個人拿金,y個人拿銀,z個人拿銅,只能向每個人要一次,最多能拿到多少硬幣?n 1e5,a i b i c i 1e9.先考慮每個人只有兩種硬幣的情況,按照a i b i 從小到大排序後,因為j i時 a j b...
hdu 4550 貪心 思維題 不錯
想了挺久,然後各種分類 終於ac,如果是現場,對自己沒信心的話,估計還是要wa,然後搜題解,發現人家都認為是簡單題,看來我還是太弱了,牡丹江沒有做出來k看來還是自己貪心和思維有問題 d是乙個deque 最樸素的演算法是,如果當前的數 d.front 那麼插入佇列的前面,否則插入佇列後面,但是有零所以...
poj1017 貪心 思維 好題
題意 運輸公司有6種規格的物品各若干件 1 1 2 2,3 3 4 4,5 5,6 6的,這六種物品都要放在6 6的箱子裡運輸,讓你求出最少用多少個箱子。解題思路 有兩種方法來做,第一種特別繁瑣,也是最直接的解決方式,那就是根據常識來貪心並模擬,量很大,另一種和這個貪心乙個思路,實現的時候非常簡便,...