P8806 [蓝桥杯 2022 国 B] 搬砖

原题链接

请跟着我假设的情景走:

我现在随便拿一块砖 \(A\) 放在地上,接着我又拿了一块砖 \(B\)
请问,\(B\) 是放在 \(A\) 上面好,还是放在 \(A\) 下面好?

分类讨论

  • \(b.v<a.w ,a.v \geq b.w\) 此时 \(B\) 能且只能放在 \(A\) 的上面,此时 \(a.v-b.v \gt b.w-a.w\)\(a.v+a.w > b.v+b.w\)

  • \(b.v<a.w,a.v<b.w\) 此时 \(B\) 没法和 \(A\) 放在一起

  • \(b.v\geq a.w,a.v<b.w\) 此时 \(B\) 能且只能放在 \(A\) 的下面,此时 \(b.v-a.v \gt a.w-b.w\)\(b.v+b.w > a.v+a.w\)

  • \(b.v\geq a.w,a.v\geq b.w\) 此时 \(B\) 放哪都可以,但是放在哪里更好呢?
    如果 \(a.v-b.w>b.v-a.w\) 则说明把 \(B\) 放在 \(A\) 上面更好,\(AB\) 之间可以插入更多砖块
    \(AB\) 之外的砖块放置不会因为 \(AB\) 的顺序改变而改变
    因为放在 \(AB\) 上面的砖块质量 \(W \leq \min(a.v,b.v)\)
    放在 \(AB\) 下面的砖块价值 \(V \geq a.w+b.w\)

综上所述,如果砖块 \(i\) 只能放在砖块 \(j\) 的下面,或者放在砖块 \(j\) 的下面更好 ,则必有 \(i.v+i.w\geq j.v+j.w\)

code

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int w,v;
}b[1105];
bool cmp(node x,node y)
{
    return x.w+x.v<=y.w+y.v;
}
int dp[2000005];
int main()
{
    int n;
    cin>>n;

    for(int i=1;i<=n;i++)
    {
        cin>>b[i].w>>b[i].v;
    }



    sort(b+1,b+1+n,cmp);
    memset(dp,-1,sizeof dp);

    dp[0]=0;
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=b[i].v;j>=0;j--)
        {
            if(dp[j]!=-1)
            {
                dp[j+b[i].w]=max(dp[j+b[i].w],dp[j]+b[i].v);
                ans=max(ans,dp[j+b[i].w]);
            }
        }
        //for(int j=1;j<=10;j++)printf("%d : %d\n",j,dp[j]);
        //puts("");

    }
    cout<<ans;
    return 0;

}

posted @ 2024-05-23 14:35  纯粹的  阅读(25)  评论(0)    收藏  举报