就是寫一下做法吧
發現 「保證每顆寶石的重量符合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 ...