problem description
最近,小明出了一些acm程式設計題,決定在hdoj舉行一場公開賽。
假設題目的數量一共是n道,這些題目的難度被評級為乙個不超過1000的非負整數,並且一場比賽至少需要乙個題,而這場比賽的難度,就是所有題目的難度之和,同時,我們認為一場比賽與本場題目的順序無關,而且題目也不會重複。
顯而易見,很容易得到如下資訊:
假設比賽只用1個題目,有n種方案;
假設比賽使用2個題目,有(n-1)*n/2種方案;
假設比賽使用3個題目,有(n-2)*(n-1)*n/6種方案;
............
假設比賽使用全部的n個題目,此時方案只有1種。
經過簡單估算,小明發現總方案數幾乎是乙個天文數字!
為了簡化問題,現在小明只想知道在所有的方案裡面第m小的方案,它的比賽難度是多少呢?
input
輸入資料的第一行為乙個整數t(1 <= t <= 20),表示有t組測試資料。
每組測試資料第一行為兩個整數n, m(0 < n, m <= 10000),表示現在有n個題目,現在要求第m小的方案的比賽難度。接下來第二行有n個數字,分別表示這n個題目的難度值。
output
對於每組測試資料,輸出一行"case #c: ans"(不包含引號),ans 表示要求的第m小的比賽難度,輸入資料保證存在第m小的方案,具體參見樣例。
sample input
25 61 1 1 1 1
5 25
1 2 3 4 5
sample output
case #1: 2case #2: 11
這個題目說一下怎麼理解吧。給你乙個排好序的陣列,怎麼盡可能快的將最小的組合數挑選出來,這就是這個題目的關鍵!!
比如給你乙個陣列a[5]=;
a[0]肯定是最小的數對吧,a[1]是第二小的數,這個是毋庸置疑的!
但是第三小的數是多少呢?是a[2]還是a[0]+a[1];這個我們就不知道了對吧,但是一定是這兩個中的乙個對吧,這就是這個題目的突破口!!
**:#include#include#includeusing namespace std;
struct node
}stu,tmp;
int a[10005];
int main()
{ int t,n,m,case=1;
cin>>t;
while(t--){
cin>>n>>m;
priority_queueq;
for(int i=0;i>a[i];
sort(a,a+n);
stu.sum=0; // 初始狀態;
stu.nextsum=a[0];
stu.nextid=0;
q.push(stu);
int cnt=0;
while(!q.empty()){
stu=q.top();
q.pop();
if(stu.nextid>=n) continue;
tmp.sum=stu.sum; // 隔乙個,直接加下乙個;
tmp.nextsum=stu.sum+a[stu.nextid+1];
tmp.nextid=stu.nextid+1;
q.push(tmp); // 不隔,直接加
tmp.sum=stu.nextsum;
tmp.nextsum=stu.nextsum+a[stu.nextid+1];
tmp.nextid=stu.nextid+1;
q.push(tmp);
cnt++;
if(cnt==m){
cout<<"case #"<
HDU4546 比賽難度
設定優先順序佇列 sum 當前和 nex 加入下個元素的和 ith 將要考慮的下個元素 讀入資料後排序,初始化佇列第乙個元素 0,a 0 0 每次出隊乙個元素,入隊 sum,sum a ith ith 1 nex,nex a ith ith 1 即是否加上a ith 都考慮進去了。這樣每次新加入的元...
HDU4546比賽難度 優先堆 思維 好題
題目鏈結 hdu4546 題目大意 給n長度的數字序列,從中取出k個元素 0解題思路 第一次做這樣組合的題,第一直覺會想用爆搜窮舉出所有組合,然後扔進multiset中維護這些值,搜尋的複雜度是指數級,記憶體也超限。發現找到第m個小的可以直接用優先佇列來模擬,因為m 10000,所以可以模擬到第m大...
hdu 4393 優先佇列)
思路 考慮si最大只有100,所以我們可以建立優先佇列陣列s 1.100 對於每個優先佇列,按第一關鍵字fi第二關鍵字id排序,每次取出所有的優先佇列裡最大值,然後直接 計算 time 1 si fi 找最大的way,將對應的優先佇列pop並輸出對應id即可。1 include2 include3 ...