启发式搜索(直观命名+详细注释版)

代码参考至oiwiki

题目:

https://www.luogu.com.cn/problem/P1048dda

#include<bits/stdc++.h>
using namespace std;

int n,m,ans;

struct Node{
    int time,value;   //耗时与价值
    double cost_performance;    //性价比
} node[102];

bool cmp(Node p,Node q){
    return p.cost_performance>q.cost_performance; //排序,性价比高的优先
}

int still(int num,int package){    //估值函数 //计算在取了num个、剩余时间package的情况下,还能取到的剩余物品的最大价值
    int tot = 0;    //统计价值
    for(int i=1;num+i<=n;i++){
        if(package>=node[i+num].time){    //如果剩余时间package>=node[i+num]的耗时
            package -= node[num+i].time;
            tot+=node[num+i].value;
        }
        else return (int)(tot+package*node[num+i].cost_performance);   //若剩余时间package<node[i+num]的耗时,则 tot+剩余时间*node[i+num]的性价比 作为估算的最大值
    }
    return tot;  //若剩余时间能取完剩余所有就返回tot
}

void dfs(int num,int package,int value){   //dfs搜索
    ans = max(ans,value);
    if(num>n) return;  //边界条件判出
    if(still(num,package)+value>ans) dfs(num+1,package,value);  //若还能取的剩余物品的估计最大值<=ans,则剪枝不搜了
    if(node[num].time<=package) dfs(num+1,package-node[num].time,value+node[num].value);    //若剩余时间package<node[num]的耗时,则剪枝不搜了
}

signed main(){
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cin>>m>>n;
    for(int i=1;i<=n;i++){
        cin>>node[i].time>>node[i].value;
        node[i].cost_performance = 1.0 * node[i].value / node[i].time;    //计算第i个物品的性价比
    }
    sort(node+1,node+1+n,cmp);
    dfs(1,m,0);
    cout<<ans;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值