題解:
一道比較好的題目
首先比較顯然的就是我們要按照a*2^b的b的順序來列舉
那麼狀態f[i][j]表示當前在b,用了a*2^b
剛開始沒想到怎麼不同層之間搞
看了題解發現非常簡單
由於每一層到最後一層有用的二進位制位至少時從自己的二進位制位開始
所以我們可以捨棄那些沒用的二進位制位
maxa(f[i][j],f[i][k]+f[i-1][(j-k)*2])
常數優化就是那個(j-k)*2可以再min個1000
另外f[i][j]其實是個字首和優化,所以剛開始都為0就可以了
不太想寫對拍然後
統計的sum陣列忘記開ll了。。。。
**:
#include usingnamespace
std;
#define ll long long
#define rint register int
#define il inline
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
const
int n=200
;int a[n],b[n],n,m,f[32][10010
];struct
re;vector
ve[32
];il
intmax(rint x,rint y)
intmain()
);
}int ans=0
; ll sum=0
; rep(i,
0,30
)
if(i)
if ((m>>i)&1
) rep(j,
1,1000) f[i][j-1]=f[i][j];
ans=max(ans,f[i][0
]); }
cout
} return0;
}
HNOI2007 夢幻島寶珠
題目 題意簡潔明瞭,就是做乙個01揹包,但是揹包的容量 w 非常大,並且給出的物品的體積都能表示成 a times 2 b,a leq 10,b leq 30 顯然這個 a 拿來做揹包的體積非常合適,於是我們按照 b 分類,設 dp 表示只使用 a times 2 i 形式的物品,湊出 j time...
HNOI2007 夢幻島寶珠 DP 折半
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 3276...
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 ...