卡牌遊戲II bfs

2021-07-30 16:46:13 字數 1721 閱讀 6305

有n張卡片,上面印著整數a1,a2,a3……an,

可以選取其中任意數量張卡片,求出乙個和s,共有2^n-1個和

要求出最小的前n個和分別是多少

題目包含多組資料。

輸入的每一行有乙個整數t(1<=t<=5)代表有t組資料

對於每組資料分為兩行:

第一行有兩個整數n,k(其中1<=n<=200000,1<=k<=min(2^n-1,200000))

第二行有n個整數,分別是a1,a2,a3……an(-10^8<=ai<=10^8)

對於每組資料,輸出的第一行為case #x:,其中x是資料編號(從1開始)

第二行到第k行,每行乙個整數,從小到大。

第二行輸出乙個非負整數,為正常需要輸出的k的數字的和 mod 99989的結果。

樣例輸入:

2

2 1

1 1

3 3

-1 0 1

樣例輸出:
case #1:

1 case #2:

99987

因為要求的是最小的值,所以最小值一定是取所有的負數,且不取任何整數的情況。

又因為少取乙個負數就相當於多拿乙個絕對值相等的正數,因此就可以把負數的和記錄下來,並將負數轉化為正數進行處理。

下一步就是從n個正數當中取數,使得和從小到大排列的問題了,這裡可以使用優先佇列的bfs進行處理。

記得負數轉化完之後,全取和全不取的情況會發生變化,要單獨考慮。

這裡的bfs用的是優化過的方式。正常的bfs是處理完第i張的情況後,將第i+1~n張卡分別加入並推入佇列,時間複雜度為o(n^2*logn/2),太高了。

因此這裡使用標記next,每次bfs的時候除了加入新卡外,額外進行一次「回溯」操作,將不取第next張卡而取第next+1張卡的情況加入佇列。因為卡片是從小到大排列的,因此這種操作既保證了小數更早處理,也大大減少了bfs的運算元(在k遠小於n^2的情況下)。

最終時間複雜度為o(klogn)。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long ll;

const

int m = 99989;

ll n,k,sum,min_,ans;

vector

card;

void bfs()

ans = (ans + min_ + val) % m;

sum++;

if (next < card.size())

qw.push(make_pair(val+card[next], next+1));//取下一張卡

}}void init()

card.push_back(t);}}

sort(card.begin(),card.end());

}int main()

}

卡牌遊戲期望

題目描述好像有點問題。應該是n種卡牌。m種稀有卡牌,且抽出不放回。對於求期望來說,相比之下我們更容易求出概率。而對於此類題目 期望往往 1 概率 暫時這麼理解的 而期望具有可加性。把所有稀有卡牌都抽一遍的期望 每次抽得乙個稀有卡牌的期望的和。至少抽出k張稀有卡牌的期望 抽出k張每次抽的乙個稀有卡牌的...

A 卡牌遊戲 III ACM

蒜頭君在玩一種卡牌遊戲,他有 n 張卡牌,每張卡牌上寫著兩個正整數 ai,bi ai 表示這張卡牌的能量值,bi表示這張卡牌的魔法值。蒜頭君要從這 n張卡牌中選出一些形成乙個卡組,用這個卡組對敵人造成傷害。乙個卡組對敵人的傷害是這個卡組中所有卡牌的能量值之和乘其中魔法值最小的一張卡牌的魔法值。蒜頭君...

B 卡牌遊戲 IV

b 卡牌遊戲 iv 蒜頭君在玩一種卡牌遊戲,他有 n 張卡牌,每張卡牌上寫著兩個正整數 ai,bi ai 表示這張卡牌的能量值,bi表示這張卡牌的魔法值。他準備一張一張打出這 n張卡牌,每張卡牌會對敵人造成的傷害是這張卡牌的能量值乘魔法值。但是蒜頭君覺得這樣把這 n張卡牌都出完對敵人造成的傷害之和還...