HDU 3001 Travelling ( 状态压缩 )

三进制解决TSP问题
本文探讨了如何使用三进制解决旅行商问题(TSP),通过预处理和动态规划,实现每个地点最多访问两次的约束,从而找到最小花费路径。

题目链接~~>

做题感悟:以前也做过类似的题目,但是这里规定每个地点只能访问 2 次 ,用二进制结果超内存,然后就百度了一下原来用三进制。

解题思路:

                大体的思路还是和 TSP 差不多,只是这里一个地点可以最多拜访两次 ,用三进制就可以解决这个问题,但是三进制不如二进制好处理。因为每个地点最多可以拜访两次,so ~> 不可以用Floyd 预处理。先预处理出来三进制的各个状态,以及各个状态的各位的状态。dp[ S ] [ i ] 代表达到状态 S 后到达 i 最小花费。

             动态方程: dp [ S + t [ j ] ] [ j ] = min (dp [ S +  t [ j ] ] [  j  ] , dp[ S ]  + d [ i ] [ j  ] )  ;  

代码:

#include<iostream>
#include<fstream>
#include<iomanip>
#include<ctime>
#include<fstream>
#include<sstream>
#include<stack>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
#include<vector>
#include<cstdio>
#include<algorithm>
#define INT __int64
using namespace std ;
const double esp = 0.00000001 ;
const int INF = 0x3f3f3f3f ;
const int mod = 1e9 + 7 ;
const int MY = 10 + 10 ;
const int MX = 59049+ 10 ;
int n ,m ;
int t[MY] ,dp[MX][MY] ,d[MY][MY] ,f[MX][MY] ;
void init() // 预处理状态
{
    t[0] = 1 ;
    for(int i = 1 ;i <= 11 ; ++i)
        t[i] = t[i-1] * 3 ;
    for(int S = 0 ; S <= 59049 ; ++S)
    {
        int temp = S ,i = 0 ;
        while(temp)
        {
            f[S][i++] = temp % 3 ;
            temp /= 3 ;
        }
    }
}
void input()
{
   int u ,v ,w ;
   memset(d ,INF ,sizeof(d)) ;
   for(int i = 0 ;i < m ; ++i)
   {
       scanf("%d%d%d" ,&u ,&v ,&w) ;
       u-- ; v-- ;
       d[u][v] = d[v][u] = min(d[u][v] ,w) ;
   }
}
void DP()
{
    int best = INF ;
    memset(dp ,INF ,sizeof(dp)) ;
    for(int i = 0 ;i < n ; ++i)
       dp[t[i]][i] = 0 ;
    for(int S = 0 ;S < t[n] ; ++S)
    {
        bool flag = true ; // 查看是否每个地点都拜访过了
        for(int i = 0 ;i < n ; ++i)
        {
          if(dp[S][i] != INF)
          {
            for(int j = 0 ;j < n ; ++j)
              if(i != j && f[S][j] <= 1 && d[i][j] != INF)
              {
                  int& ans = dp[S+t[j]][j] ;
                  ans = min(ans ,dp[S][i] + d[i][j]) ;
              }
           }
           if(!f[S][i]) flag = false ;
          }
          if(flag)
                 for(int i = 0 ;i < n ; ++i)
                     best = min(best ,dp[S][i]) ;
    }
    if(best != INF)
              cout<<best<<endl ;
    else      cout<<"-1"<<endl ;
}
int main()
{
    init() ;
    while(~scanf("%d%d" ,&n ,&m))
    {
        input() ;
        DP() ;
    }
    return 0 ;
}



内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Muti-Agent

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值