POJ 1062 题解

题目地址

这是地址

AC代码

#include <iostream>
#include <cmath>
#include <cstring>

using namespace std;

long long int mini = pow(2,60);

void calculate(long long int *list,long long int *levelDiff,long long int quantity,long long int now,long long int pass,long long int maxi,long long int low,long long int diff,long long int sum,int *mark){
    if(levelDiff[now]>maxi)maxi = levelDiff[now];
    if(levelDiff[now]<low)low = levelDiff[now];
    if(maxi-low>diff)return;
    mark[now]=1;
    for (int i = 1; i <= quantity; ++i) {
        if(now==i)continue;
        if(mark[i]==1)continue;
        if(list[now*(quantity+1)+i]!=-1){
            if(now!=1)calculate(list,levelDiff,quantity,i,now,maxi,low,diff,sum+list[pass*(quantity+1)+now],mark);
            else calculate(list,levelDiff,quantity,i,now,maxi,low,diff,0,mark);
            mark[i]=0;
        }
    }
    if(now!=1)sum+=list[now*(quantity+1)+now]+list[pass*(quantity+1)+now];
    else sum+=list[now*(quantity+1)+now];
    sum<mini?mini=sum:mini=mini;
}

int main() {
    long long int diff,quantity;
    cin>>diff>>quantity;
    long long int list[quantity+1][quantity+1];
    long long int levelDiff[quantity+1];
    int mark[quantity+1];
    memset(mark,0,sizeof(mark));
    memset(list,-1, sizeof(list));
    for (long long int i = 1; i <= quantity; ++i) {
        long long int weight,level,things;
        cin>>weight>>level>>things;
        list[i][i]=weight;
        levelDiff[i]=level;
        for (long long int j = 0; j < things; ++j) {
            long long int temp;
            cin>>temp;
            cin>>list[i][temp];
        }
    }
    calculate(*list,levelDiff,quantity,1,1,levelDiff[1],levelDiff[1],diff,0,mark);
    cout<<mini;
    return 0;
}

题解和题目思路

请不要吐槽我那个又臭又长的参数列表//为什么要用long long,问题目为什么不说清楚数据范围先好了。
这道题看别人的题解是用迪杰斯特拉算法查找最短路径做的,我自己是没写出来就是了,按照我的思路来写过于复杂。
于是我改用了DFS来解这道题
可以把物品之间的优惠兑换关系看作是图,物品为顶点,两个物品之间的优惠价格为有向带权的边,如果是自己换自己(直接购买)则为自环边,权值为原价。
建立好图之后即可用DFS对其进行搜索。从序号1的物品开始,分为继续换和不继续换两个状态。如果还有的换,则更新sum,丢入DFS的下一阶段,如果没有的换或者所有可以换的情况已经实现了,则匹配原价购买当前物品得到的总价值,与最小值比较,完成DFS后输出最小值即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值