蛋糕店恰好有對應上、中、下三層的三類蛋糕,你們知道多層蛋糕通常都是上層最小,中層其次,下層最大,否則蛋糕就不漂亮了。在知道每一種蛋糕的體積的前提下有多少符合條件的方案。 c++
看到這道題,就感受是動態規劃,題目不是說蛋糕層數的要求嗎?能夠從下往上的推,我的的第二個感受是一道搜索題,而後就這麼打着,樣例過的,手推的數據也過的。沒想到就QAQ了。算法
【暴力出奇跡】優化
爆0以後,試了一下暴力,把每一種狀況都考慮一遍,選最優值,這樣時間複雜度是O(n^2)的。至少還有點分(雖然我沒提交,但我知道啊)。我的感受就是不對。emm,我想複雜了。spa
其實計數就是暴力的優化,讀入把數字存入下標(萬幸沒有負數,哈哈)。數據卡的剛恰好。而後與暴力同樣,不停地從上往下(只但願不要掛了),找最優值。啊,果真對了(AC)。這至關因而正解了吧。blog
先附上代碼:(此代碼,不要copy謝謝)排序
#include<bits/stdc++.h> // 萬能頭 using namespace std; // 空間定義 long long n,m,k,x,a[3939],b[3939],c[3939],maxn1,maxn2,maxn3,ans,a1[514514];//定義變量 int main() { //開始瘋狂的操做 cin>>n>>m>>k; // 讀入這些值 for(int i=1; i<=n; i++) { cin>>x; //讀入 a[x]++; // 放入下標 maxn1=max(maxn1,x);//取最大值 } for(int i=1; i<=m; i++) { cin>>x; // 讀入 b[x]++; // 放入下標 maxn2=max(maxn2,x); // 取最大值 } for(int i=1; i<=k; i++) { cin>>x; // 讀入 c[x]++; // 放入下標 maxn3=max(maxn3,x); // 取最大值 } for(int i=1; i<=max(maxn3,maxn2); i++) c[i]=c[i-1]+c[i]; // 前綴處理 ,相似 dp for(int i=1; i<=max(maxn1+1,maxn2+1); i++) a1[i]=a1[i-1]+a[i-1]; // 前綴處理 ,相似dp for(int i=1; i<=maxn2; i++) ans+=(c[maxn3]-c[i])*b[i]*a1[i]; // 不停累積最優值 cout<<ans<<endl; // 輸入 return 0; // 好習慣,別忘記了 }//End;
老師後來說了這道題目,原來正解是二分,我恍然大悟(我那個時候爲啥沒有想到呢?)。ci
我知道大家對二分有點糊塗。it
我來給大家講一講。io
【二分】模板
二分查找也稱折半查找(Binary Search),它是一種效率較高的查找方法。可是,折半查找要求線性表必須採用順序存儲結構,並且表中元素按關鍵字有序排列。
二分查找對這道題沒有用,咱們解決這道題的話,要用二分答案。
【定義】
二分答案與二分查找相似,即對有着單調性的答案進行二分,大多數狀況下用於求解知足某種條件下的最大(小)值。
不是任何題目都適合使用「二分答案」的,我Sam觀察到通常有如下的一些特徵:
【模板說明】
必定要先排序。
能夠把答案當作key , 一旦當前這個序列中的數(我是根據從小到大排序的)大於key ,則右端點(r)要等於中間值(我取中間值爲(l+r)>> 1).不然就取左端點(l)要等於中間值。
從大到小同理.
【二分模板代碼】(不一樣人寫法不一樣)(這是個人模板)
int check(int key){ int l = 1,r = n; int mid; while(l<=r){ mid = (l+r) >> 1; if(key > a[mid]) l = mid+1; else if(key < a[mid])r = mid-1; else return 1; } return 0; }
介紹算法結束!
【將二分融入題目之中】
二分答案的使用能夠在查找蛋糕的最優值時候使用。
其餘同樣。
代碼就不放了。本身思考。。。。
End!