CF1303D 位運算 貪心

2022-05-16 21:19:57 字數 1436 閱讀 1684

cf1303d

題目大意:

有乙個大小為n的揹包,有m個大小為2i(i=0,1,2,3...)的物品,並且每個物品可以分成大小相同的兩份,可以一直分成到大小為1為止,問能否用這些物品把揹包恰好填滿,如果能填滿,輸出拆分物品的最小次數。

解題思路:

通過二進位制的方法,從高位到低位貪心的一位一位處理。

比如樣例一:

10  3

1   32   1

n=10,轉換成二進位制為1010,所以我們看成是1000+10.

三個物品轉換成二進位制分別為:1   100000  1

那麼我們用乙個dp[i]來表示第i位上有多少個1,比如上述的三個物品轉換成dp陣列就是dp[0]=2,dp[5]=1,其餘都為0。

那麼我們只需要從n對應的二進位制的第0位開始與dp進行比較,如果dp[i]上的數量可以滿足n的要求,則直接減去,否則就需要拆分較大的物品,即為向上借位。

具體可以看**及其注釋

1 #include 2 #include 3 #include 

4 #include 5 #include 6 #include 7 #include 8 #include 9 #include

1011

using

namespace

std;

12#define ll long long

13static

const

int white=0;14

static

const

int gray=1;15

static

const

int black=2;16

static

const

int inf=0x3f3f3f3f

;17 ll pow(ll a,ll b,ll mod)return

sum;}

18int dp[35];//

用來記錄第i位上有多少個1

19void change(int a)//

由於物品的大小都是2的n次方,所以其二進位制一定為1000---的形式

2026

intmain()

2744

if(sum//

全部裝進都裝不滿

4549

int p=0,num=0;50

while(n||dp[p]<0)51

58else

59 dp[p+1]+=dp[p]/2;//

如果低位有的多,可以給高位用

60 n>>1;//

n的最低為處理完成,進一位

61 p++;62}

63 cout

6566

return0;

67 }

view code

Bits Reverse(貪心 位運算)

給定兩個非負整數 x 和 y 規定一種操作,逆序任意三個相鄰的二進位制位。問最少需要多少次操作,能使得 x y 若不能達到,則輸出 1 1 leq t leq 10000 0 leq x,y leq 10 我們先觀察一下這個逆序操作有什麼性質,假設三個相鄰的二進位制位構成乙個三元組 a,b,c 逆序...

CF1010D Mars Over 位運算性質

題目鏈結 資料範圍 略。題解 因為每次只改乙個,改完之後改回去,這個性質很重要。發現有些葉子更改了之後,整體的答案是不變的,因為會出現 他的父親是 操作但是另乙個兒子是 0 這種.故此,我們先算出乙個節點都不更改時,每個節點的值。之後我們通過位運算,對每乙個節點維護乙個 tag 表示這個節點更改會不...

小A的位運算 貪心

題目描述 位運算是乙個非常重要的東西。而小a最近在學習位運算,小a看到了一道很簡單的例題,是說從n個數裡面選出n 1個數要讓它們或起來的值最大,小a想知道這個答案是多少。你可以幫幫他嗎?兩種方法 1.可以用貪心的思路,從大到小依次去更新或值ans,如果或到乙個數沒改變時,說明至少可以不選它,如果一直...