背包,$map$,优化。
和普通背包一样,$map$加一个$erase$优化一下就可以跑的很快了。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-6; void File() { freopen("D:\in.txt","r",stdin); freopen("D:\out.txt","w",stdout); } template <class T> inline void read(T &x) { char c=getchar(); x=0; while(!isdigit(c)) c=getchar(); while(isdigit(c)) {x=x*10+c-'0'; c=getchar();} } int n; LL m; struct X { LL x,y; }s[110]; int main() { while(~scanf("%d%lld",&n,&m)) { map<LL,LL>dp; for(int i=1;i<=n;i++) scanf("%lld%lld",&s[i].x,&s[i].y); dp[0]=0; map<LL,LL>::iterator it; for(int i=1;i<=n;i++) { it=dp.end(); --it; for (; ; ) { LL c=it->first, v=it->second; if(c+s[i].x<=m) dp[c+s[i].x]=max(dp[c+s[i].x],dp[c]+s[i].y); if(it==dp.begin()) break; --it; } it=dp.begin(); LL mx=0; for (; it != dp.end(); ) { if (it->second!=0&&it->second<=mx) dp.erase(it++); else { mx=it->second; ++it; } } } LL ans=0; it=dp.begin(); for (; it != dp.end(); ) { ans=max(ans,it->second); ++it; } printf("%lld ",ans); } return 0; }