上周的忘写了……题目没有作者……

T1.backpack

期望得分100,实际得分100.

感觉我自己真是不如以前了……以前做这种题都是秒掉的,现在怎么想了10分钟啊……

因为物品的体积和价值都非常小,我们有一句套话,“远距离贪心,近距离暴力”,所以虽然背包的体积特别大,我们可以把他压缩成1000000左右,剩下的直接暴力取性价比最高的即可。

看一下代码。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<queue>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')

using namespace std;
typedef long long ll;
const int M = 10000005;
const int INF = 1000000009;
const ll mod = 1e9+7;

ll read()
{
    ll ans = 0,op = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') op = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
    }
    return ans * op;
}

ll dp[M],m,n,a[M],b[M],v[105],mpos,ans;
double maxn;

void solve1()
{
    rep(i,1,n)
    rep(j,a[i],m) dp[j] = max(dp[j],dp[j-a[i]] + b[i]);
    printf("%lld\n",dp[m]);
}

int main()
{
    freopen("backpack.in","r",stdin);
    freopen("backpack.out","w",stdout);
    n = read(),m = read();
    rep(i,1,n) 
    {
        a[i] = read(),b[i] = read();
        v[a[i]] = max(b[i],v[a[i]]);
    }
    if(n <= 10000 && m <= 10000) solve1();
    else
    {
        rep(i,1,100)
        {
            double p = (double)(i),q = (double)(v[i]);
            if(q / p > maxn) maxn = q / p,mpos = i;
        }
        if(m > 100000)
        {
            ll k = (m - 100000) / mpos;
            m -= k * mpos,ans += k * v[mpos];
        }
        rep(i,1,100)
        rep(j,i,m) dp[j] = max(dp[j],dp[j-i] + v[i]);
        ans += dp[m];
        printf("%lld\n",ans);
    }
    return 0;
}
View Code

相关文章:

  • 2022-03-04
  • 2021-06-07
  • 2022-12-23
  • 2022-12-23
  • 2021-07-15
  • 2021-09-07
  • 2021-07-20
  • 2021-12-20
猜你喜欢
  • 2022-12-23
  • 2021-10-22
  • 2021-09-27
  • 2021-09-05
  • 2021-12-04
  • 2021-10-12
  • 2021-08-05
相关资源
相似解决方案