2023年8月7日提高組T3 選數

2021-08-05 21:46:28 字數 1504 閱讀 1612

給出n個數a[i],現在可以在其中任意選出若干個數,問有多少種選擇方案,使得這幾個數可以分成兩個和相等的集合。

第一行是乙個正整數n,第二行每行n個正整數。

輸出乙個數,表示方案數。

對於30%的資料,n<=10.

對於100%的資料,n<=20,a[i]<=100000000.

by bpm

略難每個數字前可以填1、-1、0。那麼分別代表選進1序列、2序列、不選。若要求兩序列相等,則表示1、2序列之和為0

原序列拆開兩半分別dfs,得出2個310

大小的結果陣列。排序後查詢和為0的匹配數量。

特別地,單獨的0可以作為乙個結果考慮,兩個0也可以作為結果考慮。而全不選的結果是不能計入答案的,因此ans-1

由於相同數字組成的只算一種方案,即1+4-2-3=3-1-4+2=0,所以我們需要判重。注意n並不總是偶數即可

#include 

#include

#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)

#define max(x, y) (x)>(y)?(x):(y)

#define abs(x) (x)<0?(-x):(x)

#define n 21

struct datar[2][1

<< n | 1];

int t[n], cnt[3] = ;

bool vis[1

<< n | 1];

inline

int cmp1(data a, data b)

inline

int cmp2(data a, data b)

inline

void dfs(int dep, int tot, int lim, int opt, int bn)

dfs(dep + 1, tot + t[dep], lim, opt, bn << 1 | 1);

dfs(dep + 1, tot - t[dep], lim, opt, bn << 1 | 1);

dfs(dep + 1, tot, lim, opt, bn << 1);

}int main(void)

dfs(1, 0, n / 2, 0, 0);

dfs(n / 2 + 1, 0, n, 1, 0);

std:: sort(r[0] + 1, r[0] + cnt[0] + 1, cmp1);

std:: sort(r[1] + 1, r[1] + cnt[1] + 1, cmp2);

int ans = 0;

int j = 1;

rep(i, 1, cnt[0])

int k = j;

while (r[0][i].x + r[1][k].x == 0 && k <= cnt[1])

k += 1;}}

printf("%d\n", ans - 1);

return

0;}

2023年8月16日提高組T3 旅館

有一間旅館,旅館內有n間排成一排的房間,一開始全為空。現在有m個要求 1 d表示詢問旅館內是否有連續d間空房間,有的話則輸出最小的乙個r,滿足從r開始連續d間房間均為空,同時會有人入住這d間房。若無法被滿足,則輸出0.2 l r表示把 l,r 內的房間全部設為空。第一行兩個整數n,m.接下來m行,每...

2023年8月10號提高組T3 樹

給你一棵大小為n的有根樹,每個點有點權,要求完成以下操作 v x y把點x的權值變成y e x把有根樹的根變為x q x查詢點x的子樹的最小值 第一行兩個整數n,m,表示點數和運算元。接下來n行,每行兩個數f,v,第i行的兩個數表示i的父親和i的權值,且保證f接下來m行,每行表示乙個操作。對於每個q...

2023年8月8日提高組T1 作業

小a作為乙個乖乖好學生,回到家後總是一絲不苟地完成老師布置的作業。這天,老師給小a布置了n項作業,每一項作業都有截止時間di和價值vi 你可以理解成每做完乙份作業就要快遞過去給老師,且快遞是不耗費時間的 每完成一項作業便可獲得其價值。但小a發現,自己每乙個單位時間內只能完成其中的一項作業,請你告訴小...