(這排版我真搞不懂,明明我這邊是ok的)
題目大意:
給定 m
'>m
個序列m
'>每個包含 n
'>n
個非負整數。
現在我們可以從每個序列中選擇乙個數字以形成具有 m
'>m
個整數的序列。
很明顯,我們一共可以得到 n
m'>n^m
個這種序列,然後我們可以計算每個序列中的數字之和,並得到 n
m'>n^
m 個值。
現在請你求出這些序列和之中最小的 n
'>n
個值。n
'>題解:
假設現在只有兩個序列,
a1 a2 a3 a4... an,
b1 b2 b3 b4...bn,從每乙個序列中取出乙個數求和一共有n*n種。
現在想把這n*n種結果分成n組。
首先把a排序,使它單調遞增,b是否有序無所謂。
b1+a1, b1+a2,b1+a3,b1+a4....b1+an (第一組)
b2+a1,b2+a2,b2+a3,b2+a4...b2+an(第二組)
b3+a1,b3+a2,b3+a3,b3+a4...b3+an(第三組)
....
bn+a1,bn+a2,bn+a3,bn+a4...bn+an(第n組)
可以看出,由於a是單調遞增的,所以每一組的元素也是單調遞增的。
那麼n*n種結果中最小的n個,肯定是所有組中的第乙個。
將最小的那個刪去,然後被刪結果所在組下乙個數加入最小n個數中去。(優先佇列實現)
#include#include#include
#include
#include
using
namespace
std;
const
int n=2002
;typedef pair
pii;
intt;
intm,n;
inta[n],b[n],c[n];
/*b1+a1 b1+a2 b1+a3 b1+a4 b1+a5
*/void
merge()
);
for(int i=1;i<=n;i++));}
for(int i=1;i<=n;i++) a[i]=c[i];
}int
main()
merge();
}for(int i=1;i<=n;i++) printf("
%d "
,a[i]);
printf("\n
");}
return0;
}
AcWing146 序列 貪心
給定m個序列,每個包含n個非負整數。現在我們可以從每個序列中選擇乙個數字以形成具有m個整數的序列。很明顯,我們一共可以得到n mn m nm個這種序列,然後我們可以計算每個序列中的數字之和,並得到n mn m nm個值。現在請你求出這些序列和之中最小的n個值。對於每組測試用例,均以遞增順序輸出最小的...
AcWing 145 超市 146 序列
商品有保質期和價值,要在保質期內把商品賣出才有收入,每天只能賣一件,問產品的的最大利益是多少 這道題目,我們很容易發現是有乙個貪心策略,也就是對於 t 天,我們需要在保證不賣出過期商品的前提下,賣出利潤前t大的商品.所以呢,我們可以把商品按照保質時間排序,然後建立乙個小根堆,對於每乙個數而言,如果說...
(優先佇列)P1631 序列合併
有兩個長度都是n的序列a和b,在a和b中各取乙個數相加可以得到n 2 個和,求這n 2個和中最小的n個。ai 1e9,bi 1e9,n 1e5.直接暴力用優先佇列存前n個,如果出現第乙個比當前最大值還大的值時退出迴圈保障複雜度 includeusing namespace std const int...