nyist 747 蚂蚁的难题(三)

题目链接:nyist747

解法:贪心 动态规划

思路:
如果没有 B[i]这个属性的话就是明显的 01 背包问题。
现在考虑相邻的两个物品 x,y.假设已经耗费 p 的时间,那么分别列出先做 x,y 的代价:
A[x]-(p+C[x])*B[x]+A[y]-(p+C[x]+C[y])*B[y] ①
A[y]-(p+C[y])*B[y]+A[x]-(p+C[y]+C[x])*B[x] ②
对这两个式子化简,得到 ①>② 的条件是 c[x]*b[y]<c[y]*b[x].
发现只要满足这个条件的物品对(x,y),x 在 y 前的代价永远更优。
因此可以根据这个条件进行排序,之后就是简单的 01 背包了。

这是赛后学长给的题解,比赛的时候我是用01背包写的,对花费的时间进行的排序,那时候是觉得话费时间少的应该优先做,交了以后直接WA了

 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
long long d[100005];
struct node
{
    long long a,b,c;
}s[100];
bool cmp(node x,node y)
{
    return x.c * y.b < x.b * y.c;
}
int main()
{
    int T,n,i,j;
    while(~scanf("%d%d",&T,&n))
    {
        for(i = 0; i < n; i ++)
            scanf("%lld%lld%lld",&s[i].a,&s[i].b,&s[i].c);
        memset(d,0,sizeof(d));
        sort(s,s+n,cmp);
        for(i = 0; i < n; i++)
        {
            for(j = T; j >= s[i].c ; j --)
            {
                d[j] = max(d[j],d[j-s[i].c]+s[i].a-j*s[i].b);
            }
        }
        long long ans = 0;
        for(i = 0; i <= T; i ++)
        ans = max(ans,d[i]);
        printf("%lld\n",ans);
    }
    return 0;
}
        


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值