description
給你n顆寶石,每顆寶石都有重量和價值。要你從這些寶石中選取一些寶石,保證總重量不超過w,並輸出最大的總價值。
sample input
4 10
8 95 8
4 62 5
4 13
8 95 8
4 62 5
16 75594681
393216 5533
2 77
32768 467
29360128 407840
112 68
24576 372
768 60
33554432 466099
16384 318
33554432 466090
2048 111
24576 350
9216 216
12582912 174768
16384 295
1024 76
-1 -1
sample output
1419
1050650
我們考慮折半一下。
將b大於15次方的數變成a∗2
b−
16a*2^
a∗2b−1
6,然後折半去做dp。
我們發現這樣空間和時間都會炸鍋。
於是我們可以調整一下折半的分界線,我調到10就過了。(感覺我是卡過去的)
#include #include #include #include #include using namespace std;
typedef long long ll;
const int maxn = 9 * ((1 << 16) - 1);
ll _max(ll x, ll y)
int _min(int x, int y)
int read()
while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s * f;
}struct node w1[110], w2[110]; int n1, n2;
int bin[30];
ll f1[1000000], f2[550000];
int main() memset(f1, -1, sizeof(f1));
f1[0] = 0; s1 = _min(s1, m / bin[11]);
for(int i = 1; i <= n1; i++)
} memset(f2, -1, sizeof(f2));
f2[0] = 0;
for(int i = 1; i <= n2; i++)
} ll ans = 0;
for(int i = 0; i <= s2; i++) f2[i] = _max(f2[i], f2[i - 1]);
for(int i = 0; i <= s1; i++) printf("%lld\n", ans);
} return 0;
}
HNOI2007 夢幻島寶珠
題目 題意簡潔明瞭,就是做乙個01揹包,但是揹包的容量 w 非常大,並且給出的物品的體積都能表示成 a times 2 b,a leq 10,b leq 30 顯然這個 a 拿來做揹包的體積非常合適,於是我們按照 b 分類,設 dp 表示只使用 a times 2 i 形式的物品,湊出 j time...
HNOI2007 夢幻島寶珠
題解 一道比較好的題目 首先比較顯然的就是我們要按照a 2 b的b的順序來列舉 那麼狀態f i j 表示當前在b,用了a 2 b 剛開始沒想到怎麼不同層之間搞 看了題解發現非常簡單 由於每一層到最後一層有用的二進位制位至少時從自己的二進位制位開始 所以我們可以捨棄那些沒用的二進位制位 maxa f ...
P3188 HNOI2007 夢幻島寶珠
傳送門 注意到 a,b 不大 考慮對每乙個 a 2 b 的 b 分別揹包 設 f i j 表示只考慮 b i 的物品時,容量為 j sum a 的最大價值 這個就是普通的 01 揹包 考慮把 f i j 之間合併起來,為了得到容量為 w 時的答案,我們要把 f 的含義稍微變化一下 變成 f i j ...