codeforces 913C Party Lemonade (貪心 + DFS)
阿新 • • 發佈:2019-01-29
題目大意:
有 n 種檸檬汁,第 i 種每瓶的容量為 2^(i-1) 升,價格為 Ci,問至少買 L 升檸檬汁最少花多少錢?
思路:
一看題,第一感覺是 DP,但是由於購買數可以超過 L 升,並且 L 太大了,所以不能用 DP解決。我們採取貪心的策略:優先買單價更低的。這樣會出現一個問題,剩餘量如果不夠一瓶,我們是買一瓶單價最低的呢?還是從單價更高的中拼一下呢?因為買一瓶單價最低的話會產生一點浪費。所以我們就可以按照這個思路用 DFS做。
程式碼:
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; typedef long long LL; LL n,mn; struct node { LL cost,lit; //每瓶的價格和容量 double v; //單價 /升 } a[33]; LL cmp(node a,node b) { return a.v<b.v; } void dfs(LL dep,LL res,LL ans) { //引數:當前位置,剩餘量,當前花費 int f=0; if(ans>=mn) return; //如果當前花費比最小值大則退出 if(dep==n||res<=0) { //如果搜尋完畢或者已經購買完,則更新最小值並退出 if(ans<mn) mn=ans; return; } LL x=res/a[dep].lit; //當前種檸檬汁可以買多少瓶 if(res%a[dep].lit!=0) { //如果剩餘不夠一瓶,則多買一瓶 x++; f=1; } ans+=x*a[dep].cost; //先多買一瓶當前種的 res-=x*a[dep].lit; dfs(dep+1,res,ans); if(f==1) { //如果多買了,則在回溯時還原 ans-=a[dep].cost; res+=a[dep].lit; dfs(dep+1,res,ans); } } int main() { LL i,l; while(~scanf("%lld%lld",&n,&l)) { for(i=0;i<n;i++) { scanf("%lld",&a[i].cost); a[i].lit=1<<i; a[i].v=(double)a[i].cost/a[i].lit; } sort(a,a+n,cmp); //按單價升序排序 mn=0x7fffffffffffffff; dfs(0,l,0); printf("%lld\n",mn); } return 0; }