牛客練習賽49 solution

2021-09-25 02:36:02 字數 2249 閱讀 2501

水題

有15本書,和15個**,你要分配這15個**,使得總價最小.

此外,有一些**方案,每個方案是一些書的集合,表示只要買全了這個方案的書,則最便宜的一本書免費

你最後選擇的所有方案不能有重複的書.

第一感覺就是狀壓dp 了

首先二進位制列舉子集,對於每個當前狀態,考慮可以從哪些狀態轉移過來,這時候再列舉他的子集,

時間複雜度看起來是$2^n * 2^n $ 實際上是3

n3^n

3n,寫法:

for

(int sta=

1;sta<(1

<;++sta)

}

時間複雜度分析:cn1

21+c

n22n

+cn3

23+.

..+c

nn2n

=(2+

1)n=

3n

c_n^12^1 + c_n^22^n + c_n^32^3 + ...+c_n^n2^n = (2+1)^n = 3^n

cn1​21

+cn2

​2n+

cn3​

23+.

..+c

nn​2

n=(2

+1)n

=3n具體轉移,考慮當前列舉的子集是否是某個**方案,

如果不是,直接轉移,很自然

如果是,這個時候,考慮能帶來的收益,是整個sta的1的數量,盡量取大的,最小的那個.

為什麼要看sta的1的數量呢?(而不是s),如果看了s,辣答案肯定偏大;如果看sta,這一次可能不是最大的,但總有一種方案能湊到可能最大的,

仔細體會一下…

#include

using

namespace std;

typedef

long

long ll;

int n,m;

int a[20]

;int dp[

1<<15]

;bool vis[

1<<15]

;int

main()

sort

(a+1

,a+1

+n);

for(

int i=

1;i<=m;

++i)

vis[res]=1

;}for(

int sta =

1;sta<(1

<;++sta)

else}}

cout<< sum - dp[(1

<]

}

待補

其實是個水題…然後我wa了半天

注意到當前的操作只影響左邊,辣從右往左做,一定就是最新的結果辣

先統計操作的次數,然後做相應操作即可. 樹狀陣列/線段樹均可.

#include

using

namespace std;

typedef

long

long ll;

const

int mod =

1e9+7;

const

int maxn =

1e5+10;

ll node[maxn+10]

;//存差分

int n,m;

ll add

(ll x, ll y)

struct nodeno[maxn+10]

;inline

intlowbit

(int x)

void

add(

int x, ll value,

int up)

ll get

(int x)

intmain()

for(

int i=m;i>=1;

--i)

}memset

(node,0,

sizeof

(node));

for(

int i=

1;i<=m;

++i)

}for

(int i=

1;i++i)

cout<<

get(n)

;return0;

}

待補

待補

牛客練習賽9

時間限制 c c 1秒,其他語言2秒 空間限制 c c 32768k,其他語言65536k 64bit io format lld 珂朵莉想每天都給威廉送禮物,於是她準備了n個自己的本子 她想送最多的天數,使得每天至少送乙個本子,但是相鄰兩天送的本子個數不能相同 珂朵莉最多送幾天禮物呢 第一行乙個整...

牛客練習賽15

時間限制 c c 2秒,其他語言4秒 空間限制 c c 262144k,其他語言524288k 64bit io format lld 第一次期中考終於結束啦!沃老師是個語文老師,他在評學生的作文成績時,給每位學生的分數都是乙個小於10的非負小數。amy 8.99999999999999999999...

牛客練習賽5

給你n個正整數,n 5,每個正整數大小不超過1000,最初su m 0 sum 0 每次可將su m sum 按順序加上陣列中的數,加完之後可以對sum的數字進行全排列,求最終能達到的最大值。由於n只有5,所以按照題意模擬dfs實現就可以了,注意最後一組也可以按數字進行全排列。d題 include ...