BZOJ1190 HNOI2007 夢幻島寶珠

2022-07-24 00:12:25 字數 1243 閱讀 4085

就是寫一下做法吧

發現 「保證每顆寶石的重量符合a*2^b」 這個有些奇怪

考慮從這個條件入手,用跟二進位制位有關的東西 dp

仿照 01 揹包的做法,dp 的狀態用容量來表示

設 f[i][j] 表示已選容量為 j * 2^i ,

並且已選容量的 2^i 之前到 2^0 的二進位制位上的每一位都不超過重量上限時

所能獲得的最大價值

考慮轉移,選乙個重量為 ai * 2^bi 的物品的轉移方程是

f[bi][now] = max(f[bi][now], f[bi][now - ai] + vi)

就是跑個 01 揹包

按照上面的狀態定義,顯然要從低位到高位 dp

也就是第一維從小到大做

上邊那是同層之間的轉移,根據狀態定義,低位是要對高位有貢獻的

考慮做完一位如何往接下來一位更新

顯然二進位制位之間是可以互相表示的

下面這步不太自然...

仿照 01 揹包的轉移,有下面偽**

從當前層選體積為[ j ]個 2^i = 從當前層選體積為[ j - k ]個 2^i +

從下一層選[ k * 2 + 最大容量當前二進位制位有1 ]個 2^(i - 1)

這道題這麼寫就可以過了

**:

#include #include #include #include #include #include #include #include using namespace std;

typedef long long ll;

const int maxn = 105;

int n, m;

ll ans;

int w[maxn], v[maxn];

ll f[32][1005];

vectorbel[32];

inline int rd()

while (isdigit(c))

return f ? -x : x;

}inline void getbel(int no)

bel[b].push_back(no);

}inline void clearall()

int main()

for (int i = 0; i <= 31; ++i) }}

for (int i = 1; i <= 31; ++i) }}

printf("%lld\n", f[31][0]);

}return 0;

}

狡猾的商人 bzoj1202,HNOI2005

ac通道 分析 因為每月的總收入可以為正,也可以為負,所以要比較兩個區間是否相符,當且僅當它們邊界都相同時才能比較。我們設w i 表示第1 i個月的總收入與第1 fa i 1 個月的總收入之差,及第fa i i個月的總收入。如圖。若i 1,j在同乙個集合中,則第i j個月的總收入為w j w i 1...

bzoj1190夢幻島寶珠

給你n顆寶石,每顆寶石都有重量和價值。要你從這些寶石中選取一些寶石,保證總重量不超過w,且總價值最大為,並輸出最大的總價值。資料範圍 n 100 w 2 30,並且保證每顆寶石的重量符合a 2 b a 10 b 30 輸入檔案中包含多組資料。每組資料的格式如下 第一行是兩個正整數n和w,1 n 10...

bzoj 2326 HNOI2011 數學作業

題目大意 給你n,m,求concatenate 1.n mod m的值 concatenate 1.n 代表把1到n連起來 比如n 13時 concatenate 1.n 就是12345678910111213 n 10 1 m 10 9 這題很水,對於n,將其分開,比如145,就分成1 9,10 ...