bzoj4976 dp 寶石鑲嵌

2021-08-08 07:54:55 字數 1353 閱讀 3693

description

魔法師小q擁有n個寶石,每個寶石的魔力依次為w_1,w_2,...,w_n。他想把這些寶石鑲嵌到自己的法杖上,來提公升

法杖的威力。不幸的是,小q的法杖上寶石鑲嵌欄太少了,他必須扔掉k個寶石才能將剩下的寶石鑲嵌上去。法杖的

威力等於鑲嵌在上面的所有寶石的魔力按位做或(or)運算的結果,請寫乙個程式幫助小q做出最佳的選擇,使得法

杖的威力最大。

input

第一行包含兩個正整數n,k(2

<=n<=100000,1

<=k<=100,k...,w_n(0

<=w_i<=100000),分別表示每個寶石的魔力。

output

輸出一行乙個整數,即最大的威力。
sample input

4 1

32 16 8 7

sample output

56
題解

很神奇的一道題

首先觀察魔力的大小,每個魔力大小不超過100000,那麼最大的魔力值一定不會超過2^17次方。

那麼先尋找每個數能貢獻值的位置,假如貢獻的位置多於n-k的話,那麼可以直接輸出了

不行的話,n-k就只可能小於17了,也就是n

<117

那麼採取dp做

設f[i]

[j]為前i個數,或的和為j,最多需要刪除多少個數

dp方程看**吧

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn=(1

<<17);

int a[maxn],n,k,cnt;

bool wz[20];//wz[i]=true表示i位置可以|乙個1

int f[120][maxn];//只需處理n<117的情況

int main()

int ans=0;

for(int i=0;i<17;i++)if(wz[i]==true)

for(int i=0;i<=n;i++)for(int j=0;j0][0]=0;

for(int i=1;i<=n;i++)

}for(int i=1;iif(f[n][i]>=k)ans=i;

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

return

0;}

bzoj4976寶石鑲嵌 DP

description 魔法師小q擁有n個寶石,每個寶石的魔力依次為w 1,w 2,w n。他想把這些寶石鑲嵌到自己的法杖上,來提公升 法杖的威力。不幸的是,小q的法杖上寶石鑲嵌欄太少了,他必須扔掉k個寶石才能將剩下的寶石鑲嵌上去。法杖的 威力等於鑲嵌在上面的所有寶石的魔力按位做或 or 運算的結果...

bzoj4976 寶石鑲嵌 亂搞 dp

題目描述 從 n 個數中選出 n k 個,使得它們的二進位制或 or 最大。輸出這個值。輸入第一行包含兩個正整數 n,k 2 le n le 100000,1 le k le 100,k第二行包含 n 個整數 w 1,w 2,w n 0 le w i le 100000 分別表示每個寶石的魔力。輸出...

4976 寶石鑲嵌

題目大意自己看吧 題目鏈結 題解 mx為所有val中最大的 1 如果n k log mx 的話,就直接把所有數或起來就好了。2 否則的話就dp,f i j 表示前i個和為j所用的最少數,這個很好dp,注意一下會爆空間,滾一下吧。具體詳見 by cx lzx include include inclu...