7-20測試
阿新 • • 發佈:2017-07-20
bsp swap 優化 line http 估計 多少 end log
提交: 485 解決: 110
[提交][狀態][討論版]
最便宜的選擇是第一部分選擇1 塊錢的,第二部分選擇2 塊的。但由於第二部分裏2 塊錢有兩種不同的選擇,所以第二便宜的總花費仍然是3 塊。這道題一開始想到了一個方法,可以拿五十分。另f[i]表示從前i種菜品的選擇中前k便宜的價錢。f[i]可以只從f[i-1]轉來。——如果前i-1種菜品的選擇是第k+1優的,則其算上第i種菜品後一定不會進前k便宜。這樣枚舉一下,時間復雜度O(K^2*M);50分。
問題 A: 選擇困難癥
時間限制: 1 Sec 內存限制: 128 MB提交: 485 解決: 110
[提交][狀態][討論版]
題目描述
又到吃飯時間,Polo 面對飯堂裏琳(fei)瑯(chang)滿(keng)目(die)的各種食品,又陷入了痛苦的抉擇中:該是吃手(jiao)打肉餅好呢,還是吃豆(cai)角(chong)肉片好呢?嗯……又不是天秤座怎麽會醬紫呢? 具體來說,一頓飯由M 個不同的部分組成(葷菜,素菜,湯,甜品,飲料等等),Polo 要在每個部分中選一種作為今天的午飯。俗話說的好,永遠沒有免費的午餐,每種選擇都需要有一定的花費。長者常常教導我們,便宜沒好貨,最便宜的選擇估計比較坑爹,可囊中羞澀的Polo 還要把錢省下來給某人買生日禮物,這該怎麽辦呢? 於是一個折中方案出來了:第K 便宜的組合要花多少錢?這就要靠你了。
輸入
第一行兩個數M,K,含義如上所述。 接下來M 行,先是一個整數Ai,表示第i 個部分有多少種選擇。接下來用空格分開的Ai 個整數表示每種選擇的價格。
輸出
一行一個整數表示答案。
樣例輸入
2 2 2 1 3 2 2 2
樣例輸出
3
提示
【樣例解釋】
最便宜的選擇是第一部分選擇1 塊錢的,第二部分選擇2 塊的。但由於第二部分裏2 塊錢有兩種不同的選擇,所以第二便宜的總花費仍然是3 塊。這道題一開始想到了一個方法,可以拿五十分。另f[i]表示從前i種菜品的選擇中前k便宜的價錢。f[i]可以只從f[i-1]轉來。——如果前i-1種菜品的選擇是第k+1優的,則其算上第i種菜品後一定不會進前k便宜。這樣枚舉一下,時間復雜度O(K^2*M);50分。
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; int f[100005],st[3000005],m,k,num,a[100005]; int main() { scanf("%d %d",&m,&k); for(int i=1;i<=m;i++) { scanf("%d",&num); for(int P=1;P<=num;P++) scanf("%d",&a[P]); sort(a+1,a+1+num); int tot=0; for(int j=1;j<=k&&f[j];j++) for(int w=1;w<=num;w++) { st[++tot]=f[j]+a[w]; } if(i==1) { for(int w=1;w<=num;w++) f[w]=a[w]; } sort(st+1,st+1+tot); if(i!=1) for(int j=1;j<=k;j++) f[j]=st[j; } cout<<f[k]<<endl; }
標程就是上述的暴力加上堆優化。我們只要求前k優的花費,只需要一個貪心就行了。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> using namespace std; long long n,k,a[500008],b[500008],f[11][500008],tot; long long ans; priority_queue<long long> qu; int main(){ scanf("%lld%lld",&n,&k); ans=0; for(int i=1;i<=n;i++){ scanf("%lld",&f[i][0]); for(int j=1;j<=f[i][0];j++) scanf("%lld",&f[i][j]); sort(f[i]+1,f[i]+1+f[i][0]); } tot=min(k,f[1][0]); for(int i=1;i<=tot;i++) b[i]=f[1][i]; for(int i=2;i<=n;i++){ long long flag=100000000000000; for(int j=1;j<=f[i][0];j++) for(int g=1;g<=tot;g++){ if(b[g]+f[i][j]>flag) break; if(qu.size()<k){ qu.push(b[g]+f[i][j]); if(qu.size()==k) flag=qu.top(); }else{ if(b[g]+f[i][j]<flag){ qu.pop(); qu.push(b[g]+f[i][j]); flag=qu.top(); } } } tot=0; while(!qu.empty()){ b[++tot]=qu.top(); qu.pop(); } for(int i=1;i<=tot/2;i++){ swap(b[i],b[tot-i+1]); } } printf("%lld",b[k]); }
7-20測試