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 運算的結果...