jzoj 3891 钻石交易

本文介绍了一种结合分层SPFA算法与二进制状态压缩技术解决最优钻石买卖路径问题的方法。通过记录不同城市的钻石买卖状态,实现了在有限时间内找到旅行者能够获得的最大利润。

Description

这里写图片描述

Input

这里写图片描述

Output

这里写图片描述

Sample Input

4 5 2 7 1
0 0 
10 0
0 8
100 10
1 2 5
1 3 10
1 4 8
2 3 4
2 4 6

Sample Output

16
【样例说明】
最优方案为:先从城市1到城市2,在城市2卖掉第一颗钻石,然后到城市4,卖掉第二颗钻石并结束旅行。

Data Constraint

这里写图片描述


解题思路

分层spfa+二进制记录钻石是否买掉。
用f[i][p]表示在第i个城市,钻石情况为p时的最多剩余钱数,每到一个城市i,分别更新能去到的城市的值以及在当前城市卖钻石的值。
最后输出最大值就可以了。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;

const int N=1510;
const int T=4010;
const int M=1200;
const int maxn=1000000;

struct note
{
    int x,y,l,ne;
};

int dis[N][M],a[N][12],t[N],q[N*M],last[N];
note side[T];
int n,tt,m,k,s;

void init()
{
    memset(last,0,sizeof(last));
    scanf("%d%d%d%d%d",&n,&tt,&m,&k,&s);
    int i,j;
    for (i=1;i<=n;i++)
      for (j=1;j<=m;j++)
        scanf("%d",&a[i][j]);
    for (i=1;i<=tt;i++) 
    {
        scanf("%d%d%d",&side[i].x,&side[i].y,&side[i].l);
        side[i].ne=last[side[i].x];
        last[side[i].x]=i;
    }
    for (i=1;i<=n;i++)
      for (j=0;j<=1<<(m-1);j++)
        dis[i][j]=-maxn;
}

int main()
{
    init();
    int ans=0;
    int i,j,l,p,head,tail;
    for (int d=0;d<=((1<<m)-1);d++)
    {
        tail=1; head=0;
        q[1]=s; 
        dis[s][d]=k;
        int f=d;
        memset(t,0,sizeof(t));
        for (int e=1;e<=m;e++)
        { 
          if (f%2==1) dis[s][d]+=a[s][e];
          f=f/2;
        }
        t[s]=1;
        for (int e=1;e<=n;e++)
          if (dis[e][d]!=-maxn) {tail++; q[tail]=e;}
        ans=k;
        while (head<tail)
        {
            head++;
            i=q[head]; 
            l=last[i];
            //printf("%d %d %d\n",i,d,dis[i][d]);
            ans=max(ans,dis[i][d]);
            while (l!=0)
            {
                  p=side[l].y;
                  if ((dis[i][d]-side[l].l>=0)&&(dis[i][d]-side[l].l>dis[p][d]))
                  {
                     dis[p][d]=dis[i][d]-side[l].l;
                     if (t[p]==0)
                     {
                        tail++;
                        q[tail]=p; 
                        t[p]=1;
                     }
                  }
                  l=side[l].ne;
            }
            for (l=1;l<=m;l++)
              if ((d&(1<<(l-1)))==0)
              {
                p=d|(1<<(l-1));
                //printf("%d %d %d\n",i,j,p);
                if (dis[i][p]<dis[i][d]+a[i][l]) dis[i][p]=dis[i][d]+a[i][l];
              }
              t[i]=0;
        }
    }
    printf("%d\n",ans);
    return 0;
}
本研究基于扩展卡尔曼滤波(EKF)方法,构建了一套用于航天器姿态与轨道协同控制的仿真系统。该系统采用参数化编程设计,具备清晰的逻辑结构和详细的代码注释,便于用户根据具体需求调整参数。所提供的案例数据可直接在MATLAB环境中运行,无需额外预处理步骤,适用于计算机科学、电子信息工程及数学等相关专业学生的课程设计、综合实践或毕业课题。 在航天工程实践中,精确的姿态与轨道控制是保障深空探测、卫星组网及空间设施建设等任务成功实施的基础。扩展卡尔曼滤波作为一种适用于非线性动态系统的状态估计算法,能够有效处理系统模型中的不确定性与测量噪声,因此在航天器耦合控制领域具有重要应用价值。本研究实现的系统通过模块化设计,支持用户针对不同航天器平台或任务场景进行灵活配置,例如卫星轨道维持、飞行器交会对接或地外天体定点着陆等控制问题。 为提升系统的易用性与教学适用性,代码中关键算法步骤均附有说明性注释,有助于用户理解滤波器的初始化、状态预测、观测更新等核心流程。同时,系统兼容多个MATLAB版本(包括2014a、2019b及2024b),可适应不同的软件环境。通过实际操作该仿真系统,学生不仅能够深化对航天动力学与控制理论的认识,还可培养工程编程能力与实际问题分析技能,为后续从事相关技术研究或工程开发奠定基础。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值