bzoj4976寶石鑲嵌 DP

2021-08-07 05:37:42 字數 1289 閱讀 6161

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 > k +log w,那麼顯然所有 1 都可以保留,否則現在 n ≤ k +log w。

考慮 dp,設 fi,j 表示考慮前 i 個數,保留的數的 or 是 j 時,最多能刪除多少個數。

時間複雜度 o(n + (k + log w)w)。

題解如上。

差不多了,只不過直接dp不大好寫,f[i][j]表示用最少的數能到達j狀態,轉移就很好寫了。

#include

#include

#include

#include

#include

#include

#define fo(i,a,b) for(int i=a;i<=b;i++)

#define fd(i,a,b) for(int i=a;i>=b;i--)

using

namespace

std;

const

int n=1e5+5;

const

int inf=0x3f3f3f3f;

int n,m,mx,k;

int a[n];

int f[200][200000],bin[n];

int main()

memset(f,inf,sizeof(f));

f[0][0]=0;

bin[0]=1;

fo(i,1,17)bin[i]=bin[i-1]*2;

fo(i,0,n-1)

fo(j,0,bin[17]-1)if (f[i][j]1][j]=min(f[i+1][j],f[i][j]);

f[i+1][j|a[i+1]]=min(f[i+1][j|a[i+1]],f[i][j]+1);

}int ans=0;

fd(i,bin[17]-1,0)

if (f[n][i]<=n-k)

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

}

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 分別表示每個寶石的魔力。輸出...

bzoj 4976 寶石鑲嵌 動態規劃

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

bzoj4976 dp 寶石鑲嵌

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