弱校胡策 深渊

题目描述
曹操决定考试时找“鬼才”郭嘉来帮忙作弊,可他突然想起这时郭嘉好像真的成了鬼了,(众所周知,郭嘉死的早)于是干脆让郭嘉在考试时给他托梦,(他负责睡觉^(* ̄(oo) ̄)^)由于曹操睡觉打呼的声音吵到了别人,所以天道将他丢入了了梦之深渊,深渊的深度为D,而且在这里几乎任何东西都会很快被吞噬,幸好曹操有诸侯称号护体,暂时不会被吞噬,可称号只能帮他维持10s的时间。于是郭嘉从地狱带来了深渊币,并会在约定好的时间将深渊币投入深渊。曹操可以用深渊币回复称号能力(无上限)或者转化成可以存在于深渊的天梯,但深渊币也不尽相同(即转化的天梯高度和恢复的能量可能不同),若曹操与郭嘉会和将一定能考满分,而曹操一定会采取最佳策略,汉献帝刘协想知道曹操从梦中出来的时间,以便破坏这次见面,但由于手
下无可用之才,于是找到了你……
输入描述
第一行为2个整数, D 和 G (1 <= G <= 100), G为被投入深渊的深渊币的数量。
第二到第G+1行每行包括3个整数: T (0 < T <= 1000),表示深渊币被投进井中的时间;
F (1 <= F <= 30),表示该深渊币能恢复曹操称号能力的时间;和 H (1 <= H <= 25),该深渊币转化成的天梯的高度。输出描述 如果曹操可以走出深渊,输出一个整数表示最早什么时候可以走出;否则输出曹操最长可以存活多长时间。
样例输入
20 4
5 4 9
9 3 2
12 6 10
13 1 1
样例输出
13

题目来源:http://codevs.cn/problem/1684/

60分:爆搜+一些不知是否有用的小优化

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=2000005;
struct dqs
{
    int tim,hf,tt;
}hh[maxn];  
int d,g,flag=0;
bool cmp(dqs a,dqs b)
{
    if(a.tim==b.tim)
    {
        if(a.hf==b.hf) return a.tt<b.tt;
        return a.hf<b.hf;
    }
    return a.tim<b.tim;
}
void dfs(int i,int pret,int preh)
{
    if(flag==2) return;
    else if(i>g) return;
    else if(hh[i].tim>pret) return;
    else
    {
        preh+=hh[i].tt;
        if(preh>=d)
        {
            flag=2;
            printf("%d\n",hh[i].tim);
            return;
        }
        dfs(i+1,pret,preh);
        preh-=hh[i].tt;
        dfs(i+1,pret+hh[i].hf,preh);
    }
}
int main()
{
    scanf("%d%d",&d,&g);
    for(int i=1;i<=g;i++)
        scanf("%d%d%d",&hh[i].tim,&hh[i].hf,&hh[i].tt);
    sort(hh+1,hh+g+1,cmp);
    int sj=10;
    for(int i=1;i<=g;i++)   //最长存活 
    {
        if(sj<hh[i].tim)
        {
        //  cout<<i<<" "<<hh[i].tim<<endl;
            flag=1;
        //  cout<<"11111"<<endl;
            printf("%d\n",sj);
            break;
        }
        else sj+=hh[i].hf;
    }
    if(flag==0)
    {
        int tmp=0;
        for(int i=1;i<g;i++)
            tmp+=hh[i].tt;
        if(tmp<d)
            printf("%d\n",sj);
        else
        {
            dfs(1,10,0);
        //  cout<<flag<<" 2222"<<endl;
            if(flag!=2)
                printf("%d\n",sj);  
        }
    }
    return 0;
}

100分:
利用01背包变形。
以下来自loi_wzhd的题解分析:
在这道题中,由于时间在不断变化的过程中,曹操的能量会不断减少,所以使得这道题看起来会很麻烦。那么,如何处理时间的问题呢?
实际上,我们并不需要每次把时间都减去这些能量,只需要判断总能量与时间大小关系就知道曹操是否会被吞噬。
既然不需要减去能量,我们只需要记录到达某一高度的最大能量值就可以了。
这就成了01背包的变形。
高度就是背包的容积,能量就是背包的价值。
不同的是,在这道题中,要先按照时间排一遍序,(题目并没有说一定按照时间先后给你物品),并且在某高度下,只有曹操能活到那个时间才能够使用这个物品(特判一下物品的价值是否大于等于时间)。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=2000005;
struct dqs
{
    int tim,hf,tt;
}hh[maxn];
int dp[maxn];
int d,g;
bool cmp(dqs a,dqs b)
{
    if(a.tim==b.tim)
    {
        if(a.hf==b.hf) return a.tt<b.tt;
        return a.hf<b.hf;
    }
    return a.tim<b.tim;
}
int main()
{
    scanf("%d%d",&d,&g);
    for(int i=1;i<=g;i++)
        scanf("%d%d%d",&hh[i].tim,&hh[i].hf,&hh[i].tt);
    sort(hh+1,hh+g+1,cmp);
    dp[0]=10;
    for(int i=1;i<=g;i++)
    {
        for(int j=d;j>=0;j--)
        {
            if(dp[j]>=hh[i].tim)
            {
                if(j+hh[i].tt>=d)
                {
                    printf("%d\n",hh[i].tim);
                    return 0;
                }
                dp[j+hh[i].tt]=max(dp[hh[i].tt+j],dp[j]);
                dp[j]+=hh[i].hf;
            }
        }
    }
    printf("%d\n",dp[0]);   
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值