codeforces E - Selling Souvenirs

 

#记录一下自己一步一步跳进去的坑

1.比如说还在纠结为什么w明明不会太大为什么开longlong

因为不开的话这边会爆掉阿:    return a.c*b.w>b.c*a.w;

2.比如说我的做法是把性价比排序,然后直接贪心选,剩下的再dp,同时卡一下边界

but一直卡不过去,开大了过不去T,开小了同样过不去wa

这是因为直接贪心选这个做法,不能保证正确性(属于我不能证伪,但数据测出来如此hh

 

看了一下其他人的写法,是贪心排序+dp,然后dp的优化在于: 

for(int j=up;j>=max(f[i].w,1ll*up-1000);j--)

时间复杂度:O(1000*N),甚至1000还可以更小点,我觉得10左右就差不多,有人说6

这是因为在排序后,设想当前枚举到的容量上限为150,其实前100个最优解已经是固定的了

越枚举到后面,这个物件的价值越小,越不可能代替前面的更优的物件,去更新前面的答案

如果不会证明的话1000也够用啦>_<

#include<bits/stdc++.h>
using namespace std;
struct lys{long long w,c;}f[100007];
long long dp[300007];
int n,m;
bool cmp(lys a,lys b){
    return a.c*b.w>b.c*a.w;
}
void solve(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>f[i].w>>f[i].c;
    
    sort(f+1,f+n+1,cmp);
    long long up=0;
    
    for(int i=1;i<=n;i++)
    {
        up=min(up+f[i].w,1ll*m);
        for(int j=up;j>=max(f[i].w,1ll*up-1000);j--)
         dp[j]=max(dp[j],dp[j-f[i].w]+1ll*f[i].c);
    }
    long long ans=0;
    for(int i=1;i<=up;i++){
        ans=max(ans,dp[i]);
    }
    cout<<ans;
}
int main(){
    //freopen("lys.in","r",stdin);
    solve();
}

 

posted @ 2022-07-18 15:59  liyishui  阅读(16)  评论(0编辑  收藏  举报