$01$背包。
数据范围:物品个数小于等于$3000$,背包大小小于等于$1000000$。
$map<int,long long>dp$,用$map$去做$dp$,可以少遍历很多状态,可以$AC$。
还可以做一些优化,例如费用大,但是价值小的状态可以直接删除。
#include <cstdio> #include <cmath> #include <cstring> #include <map> #include <algorithm> using namespace std; int B; int c; long long v; int sz; int cc[1000010]; long long vv[1000010]; map<int,long long>dp; int main() { scanf("%d",&B); dp[0] = 0; map<int,long long>::iterator it; while(~scanf("%d%lld",&c,&v)) { sz=0; for(it = dp.begin();it != dp.end(); ++it) { int ccc = it->first; long long vvv = it->second; if(ccc+c>B) continue; cc[sz] = ccc+c; vv[sz] = vvv+v; sz++; } for(int i=0;i<sz;i++) { if(dp.count(cc[i])==0) { dp[cc[i]] = vv[i]; } else dp[cc[i]] = max(dp[cc[i]],vv[i]); } } long long ans= 0; for(it = dp.begin();it != dp.end(); ++it) { ans = max(ans,it->second); } printf("%lld ",ans); return 0; }