atcoder Educational DP Contest x-Tower

题意:
有n堆物品,每堆物品都有三个值,重量w,承重s,价值v,可以将这些物品进行堆积,堆积在每个物品上方的总重量必须小于等于其承重,问堆积起来的物品的最大总价值是多少。

题解:
假设只有两个物品 w1,s1 / w2,s2,如果第一个物品在上面,那么还能放的重量为s2-w1,反之就是s1-w2。
如果s2-w1>s1-w2,即s2+w2>s1+w1,贪心的去想,我们必定是选择还能放重量多的方案。由此可以得到结论,对s+w按照升序排序,大的选择放下面,最后就是01背包问题。

代码:

#include<bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int MAXN=1e3+5;
const int mod=1e9+7;
struct node
{
    
    
    int w,s,v;
}f[MAXN];
ll dp[10000005];
bool cmp(node a,node b)
{
    
    
    return a.w+a.s<b.w+b.s;
}
const ll inf=-0x3f3f3f3f3f;
int main()
{
    
    
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
    
    
        cin>>f[i].w>>f[i].s>>f[i].v;
    }
    sort(f+1,f+1+n,cmp);
    memset(dp,inf,sizeof dp);
    dp[0]=0;
    for(int i=1;i<=n;i++)
    {
    
    
        for(int j=f[i].s;j>=0;j--)
        {
    
    
            dp[j+f[i].w]=max(dp[j+f[i].w],dp[j]+f[i].v);
        }
    }
    ll ans=0;
    for(int i=0;i<=10000000;i++)
    {
    
    
        ans=max(ans,dp[i]);
    }
    cout<<ans<<endl;
}

猜你喜欢

转载自blog.csdn.net/weixin_45755679/article/details/112998708
今日推荐