C++状压DP

状压DP,对应蓝桥云课坐标搜索 代码框架见下

cpp 复制代码
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;

#define maxn 16
#define type double
#define dptype DPType::MIN
typedef type(*dis_func)(int a, int b);

enum DPType{
  MIN = 0, //最大值
  MAX = 1, //最小值
  NUM = 2, //方案数
};
//
//
type dp[1 << maxn][maxn];
type dis[maxn][maxn];
type HamiltonDP_Opt(type a, type b, type c){
  if(dptype == DPType::MIN){
    return min(a, b+c);
  }else if(dptype == DPType::MAX){
    return max(a, b+c);
  }else if(dptype == DPType::NUM){
    return a + b * c;
  }
}

type HamiltonDP_ValueInit(){
  if(dptype == DPType::MIN){
    return 0;
  }else if(dptype == DPType::MAX){
    return 0;
  }else if(dptype == DPType::NUM){
    return 1;
  }
}

type HamiltonDP_ValueInf(){
  if(dptype == DPType::MIN){
    return 1000000000;
  }else if(dptype == DPType::MAX){
    return -1000000000;
  }else if(dptype == DPType::NUM){
    return 0;
  }
}

void HamiltonDP_Init(int n, dis_func df){
  memset(dp, -1, sizeof(dp));
  for(int i=0; i<n; ++i){
    for(int j=0; j<n; ++j){
      dis[i][j] = df(i, j);
    }
  }
}

// state:二进制的1101 代表0 2 3 这三个顶点已经被访问的情况
//  n   :代表总共有多少个顶点
//  pre :代表这条路径上的最后一个顶点
type HamiltonDP_DFS(int state, int n, bool isCircle, int start, int pre){
  if(state + 1 == (1 << n)){
    type init = HamiltonDP_ValueInit();
    type inf = HamiltonDP_ValueInf();
    if(isCircle){
      //最小值:min(inf, init + dis[pre][start]);
      //最大值:max(inf, init + dis[pre][start]); 
      return HamiltonDP_Opt(inf, init, dis[pre][start]);
    }
    return init;
  }
  type& ans = dp[state][pre];
  if(ans >= 0){
    return ans;
  }
  ans = HamiltonDP_ValueInf();
  for(int i=0; i<n; ++i){
    if(state & (1 << i)){
      continue;
    }
    type d = dis[pre][i];
    type next = HamiltonDP_DFS(state | (1 << i), n, isCircle, start, i);
    ans = HamiltonDP_Opt(ans, d, next);    
  }
  return ans;
}

type HamiltonDP_Solve(dis_func df, int n, bool isCircle, int start = -1){
  // 初始化
  HamiltonDP_Init(n, df);
  type ans = HamiltonDP_ValueInf();
  type ini = HamiltonDP_ValueInit();
  if(start == -1){
    for(int i = 0; i < n; ++i){
      type v = HamiltonDP_DFS((1 << i), n, isCircle, i, i);
      ans = HamiltonDP_Opt(ans, v, ini);
    }
  }else{
      type v = HamiltonDP_DFS((1 << start), n, isCircle, start, start);
      ans = HamiltonDP_Opt(ans, v, ini);   
  }
  return ans;
}

int n;
int x[maxn], y[maxn];
type d(int a, int b){
  return sqrt((x[a] - x[b]) * (x[a] - x[b]) + 
  (y[a] - y[b]) * (y[a] - y[b]));
}

int main()
{
  cin >> n;
  n++;
  x[0] = y[0] = 0;
  for(int i=1; i<n; ++i){
    cin >> x[i] >> y[i];
  }
  printf("%.2lf\n", HamiltonDP_Solve(d, n, false, 0));

  // 请在此输入您的代码
  return 0;
}

代码练习1 回路计数 对应蓝桥云课 代码见下

cpp 复制代码
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;

#define maxn 21
#define type long long
#define dptype DPType::NUM
typedef type(*dis_func)(int a, int b);

enum DPType{
  MIN = 0, //最大值
  MAX = 1, //最小值
  NUM = 2, //方案数
};
//
//
type dp[1 << maxn][maxn];
type dis[maxn][maxn];
type HamiltonDP_Opt(type a, type b, type c){
  if(dptype == DPType::MIN){
    return min(a, b+c);
  }else if(dptype == DPType::MAX){
    return max(a, b+c);
  }else if(dptype == DPType::NUM){
    return a + b * c;
  }
}

type HamiltonDP_ValueInit(){
  if(dptype == DPType::MIN){
    return 0;
  }else if(dptype == DPType::MAX){
    return 0;
  }else if(dptype == DPType::NUM){
    return 1;
  }
}

type HamiltonDP_ValueInf(){
  if(dptype == DPType::MIN){
    return 1000000000;
  }else if(dptype == DPType::MAX){
    return -1000000000;
  }else if(dptype == DPType::NUM){
    return 0;
  }
}

void HamiltonDP_Init(int n, dis_func df){
  memset(dp, -1, sizeof(dp));
  for(int i=0; i<n; ++i){
    for(int j=0; j<n; ++j){
      dis[i][j] = df(i, j);
    }
  }
}

// state:二进制的1101 代表0 2 3 这三个顶点已经被访问的情况
//  n   :代表总共有多少个顶点
//  pre :代表这条路径上的最后一个顶点
type HamiltonDP_DFS(int state, int n, bool isCircle, int start, int pre){
  if(state + 1 == (1 << n)){
    type init = HamiltonDP_ValueInit();
    type inf = HamiltonDP_ValueInf();
    if(isCircle){
      //最小值:min(inf, init + dis[pre][start]);
      //最大值:max(inf, init + dis[pre][start]); 
      return HamiltonDP_Opt(inf, init, dis[pre][start]);
    }
    return init;
  }
  type& ans = dp[state][pre];
  if(ans >= 0){
    return ans;
  }
  ans = HamiltonDP_ValueInf();
  for(int i=0; i<n; ++i){
    if(state & (1 << i)){
      continue;
    }
    type d = dis[pre][i];
    type next = HamiltonDP_DFS(state | (1 << i), n, isCircle, start, i);
    ans = HamiltonDP_Opt(ans, d, next);    
  }
  return ans;
}

type HamiltonDP_Solve(dis_func df, int n, bool isCircle, int start = -1){
  // 初始化
  HamiltonDP_Init(n, df);
  type ans = HamiltonDP_ValueInf();
  type ini = HamiltonDP_ValueInit();
  if(start == -1){
    for(int i = 0; i < n; ++i){
      type v = HamiltonDP_DFS((1 << i), n, isCircle, i, i);
      ans = HamiltonDP_Opt(ans, v, ini);
    }
  }else{
      type v = HamiltonDP_DFS((1 << start), n, isCircle, start, start);
      ans = HamiltonDP_Opt(ans, v, ini);   
  }
  return ans;
}

int n;
int x[maxn], y[maxn];

int gcd(int a, int b){
  return !b ? a : gcd(b, a%b);
}


type d(int a, int b){
  return gcd(a+1, b+1) == 1;
}

int main()
{
  int n = 21;
  printf("%.lld\n", HamiltonDP_Solve(d, n, true, 0));

  // 请在此输入您的代码
  return 0;
}

代码练习 2 星球 对应蓝桥云课 代码见下

cpp 复制代码
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;

#define maxn 18
#define type double
#define dptype DPType::MIN
typedef type(*dis_func)(int a, int b);

enum DPType{
  MIN = 0, //最大值
  MAX = 1, //最小值
  NUM = 2, //方案数
};
//
//
type dp[1 << maxn][maxn];
type dis[maxn][maxn];
type HamiltonDP_Opt(type a, type b, type c){
  if(dptype == DPType::MIN){
    return min(a, b+c);
  }else if(dptype == DPType::MAX){
    return max(a, b+c);
  }else if(dptype == DPType::NUM){
    return a + b * c;
  }
}

type HamiltonDP_ValueInit(){
  if(dptype == DPType::MIN){
    return 0;
  }else if(dptype == DPType::MAX){
    return 0;
  }else if(dptype == DPType::NUM){
    return 1;
  }
}

type HamiltonDP_ValueInf(){
  if(dptype == DPType::MIN){
    return 1000000000;
  }else if(dptype == DPType::MAX){
    return -1000000000;
  }else if(dptype == DPType::NUM){
    return 0;
  }
}

void HamiltonDP_Init(int n, dis_func df){
  memset(dp, -1, sizeof(dp));
  for(int i=0; i<n; ++i){
    for(int j=0; j<n; ++j){
      dis[i][j] = df(i, j);
    }
  }
}

// state:二进制的1101 代表0 2 3 这三个顶点已经被访问的情况
//  n   :代表总共有多少个顶点
//  pre :代表这条路径上的最后一个顶点
type HamiltonDP_DFS(int state, int n, bool isCircle, int start, int pre){
  if(state + 1 == (1 << n)){
    type init = HamiltonDP_ValueInit();
    type inf = HamiltonDP_ValueInf();
    if(isCircle){
      //最小值:min(inf, init + dis[pre][start]);
      //最大值:max(inf, init + dis[pre][start]); 
      return HamiltonDP_Opt(inf, init, dis[pre][start]);
    }
    return init;
  }
  type& ans = dp[state][pre];
  if(ans >= 0){
    return ans;
  }
  ans = HamiltonDP_ValueInf();
  for(int i=0; i<n; ++i){
    if(state & (1 << i)){
      continue;
    }
    type d = dis[pre][i];
    type next = HamiltonDP_DFS(state | (1 << i), n, isCircle, start, i);
    ans = HamiltonDP_Opt(ans, d, next);    
  }
  return ans;
}

type HamiltonDP_Solve(dis_func df, int n, bool isCircle, int start = -1){
  // 初始化
  HamiltonDP_Init(n, df);
  type ans = HamiltonDP_ValueInf();
  type ini = HamiltonDP_ValueInit();
  if(start == -1){
    for(int i = 0; i < n; ++i){
      type v = HamiltonDP_DFS((1 << i), n, isCircle, i, i);
      ans = HamiltonDP_Opt(ans, v, ini);
    }
  }else{
      type v = HamiltonDP_DFS((1 << start), n, isCircle, start, start);
      ans = HamiltonDP_Opt(ans, v, ini);   
  }
  return ans;
}

int n;
int x[maxn], y[maxn], z[maxn], w[maxn+1];
type d(int a, int b){
  return sqrt((x[a] - x[b]) * (x[a] - x[b]) + 
  (y[a] - y[b]) * (y[a] - y[b])
  + (z[a] - z[b]) * (z[a] - z[b])) * w[b];
}

int main()
{
  cin >> n;
  for(int i=0; i<n; ++i){
    cin >> x[i] >> y[i] >> z[i] >> w[i];
  }
  printf("%.2lf\n", HamiltonDP_Solve(d, n, false, -1));

  // 请在此输入您的代码
  return 0;
}

代码练习 3 对应蓝桥云课 补给 代码见下

cpp 复制代码
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;

#define maxn 20
#define type double
#define dptype DPType::MIN
typedef type(*dis_func)(int a, int b);

enum DPType{
  MIN = 0, //最大值
  MAX = 1, //最小值
  NUM = 2, //方案数
};
//
//
type dp[1 << maxn][maxn];
type dis[maxn][maxn];
type HamiltonDP_Opt(type a, type b, type c){
  if(dptype == DPType::MIN){
    return min(a, b+c);
  }else if(dptype == DPType::MAX){
    return max(a, b+c);
  }else if(dptype == DPType::NUM){
    return a + b * c;
  }
}

type HamiltonDP_ValueInit(){
  if(dptype == DPType::MIN){
    return 0;
  }else if(dptype == DPType::MAX){
    return 0;
  }else if(dptype == DPType::NUM){
    return 1;
  }
}

type HamiltonDP_ValueInf(){
  if(dptype == DPType::MIN){
    return 1000000000;
  }else if(dptype == DPType::MAX){
    return -1000000000;
  }else if(dptype == DPType::NUM){
    return 0;
  }
}

void HamiltonDP_Init(int n, dis_func df){
  memset(dp, -1, sizeof(dp));
  for(int i=0; i<n; ++i){
    for(int j=0; j<n; ++j){
      dis[i][j] = df(i, j);
    }
  }
}

// state:二进制的1101 代表0 2 3 这三个顶点已经被访问的情况
//  n   :代表总共有多少个顶点
//  pre :代表这条路径上的最后一个顶点
type HamiltonDP_DFS(int state, int n, bool isCircle, int start, int pre){
  if(state + 1 == (1 << n)){
    type init = HamiltonDP_ValueInit();
    type inf = HamiltonDP_ValueInf();
    if(isCircle){
      //最小值:min(inf, init + dis[pre][start]);
      //最大值:max(inf, init + dis[pre][start]); 
      return HamiltonDP_Opt(inf, init, dis[pre][start]);
    }
    return init;
  }
  type& ans = dp[state][pre];
  if(ans >= 0){
    return ans;
  }
  ans = HamiltonDP_ValueInf();
  for(int i=0; i<n; ++i){
    if(state & (1 << i)){
      continue;
    }
    type d = dis[pre][i];
    type next = HamiltonDP_DFS(state | (1 << i), n, isCircle, start, i);
    ans = HamiltonDP_Opt(ans, d, next);    
  }
  return ans;
}

type HamiltonDP_Solve(dis_func df, int n, bool isCircle, int start = -1){
  // 初始化
  HamiltonDP_Init(n, df);
  type ans = HamiltonDP_ValueInf();
  type ini = HamiltonDP_ValueInit();
  if(start == -1){
    for(int i = 0; i < n; ++i){
      type v = HamiltonDP_DFS((1 << i), n, isCircle, i, i);
      ans = HamiltonDP_Opt(ans, v, ini);
    }
  }else{
      type v = HamiltonDP_DFS((1 << start), n, isCircle, start, start);
      ans = HamiltonDP_Opt(ans, v, ini);   
  }
  return ans;
}

int n;
type d[maxn][maxn];
int x[maxn], y[maxn];
type df(int a, int b){
  return d[a][b];
}

int main()
{
  int n, D;
  cin >> n >> D;
  for(int i=0; i<n; ++i){
    cin >> x[i] >> y[i];
  }
  for(int i=0; i<n; ++i){
    for(int j=0; j<n; ++j){
      int xx = x[i] - x[j];
      int yy = y[i] - y[j];
      int di = xx*xx + yy*yy;
      if(di <= (long long)D * D){
      d[i][j] = sqrt(di);
    }else{
      d[i][j] = HamiltonDP_ValueInf();
      }
    }
  }
  for(int k=0; k<n; ++k){
    for(int i=0; i<n; ++i){
      for(int j=0; j<n; ++j){
        if(d[i][k] + d[k][j] < d[i][j]){
          d[i][j] = d[i][k] + d[k][j];
        }
      }
    }
  }
  printf("%.2lf\n", HamiltonDP_Solve(df, n, true, 0));
  // 请在此输入您的代码
  return 0;
}
相关推荐
choke2337 分钟前
[特殊字符] Python异常处理
开发语言·python
云中飞鸿7 分钟前
linux中qt安装
开发语言·qt
少控科技21 分钟前
QT第6个程序 - 网页内容摘取
开发语言·qt
darkb1rd22 分钟前
八、PHP SAPI与运行环境差异
开发语言·网络安全·php·webshell
历程里程碑24 分钟前
Linux20 : IO
linux·c语言·开发语言·数据结构·c++·算法
郝学胜-神的一滴26 分钟前
深入浅出:使用Linux系统函数构建高性能TCP服务器
linux·服务器·开发语言·网络·c++·tcp/ip·程序人生
天若有情67327 分钟前
【自研实战】轻量级ASCII字符串加密算法:从设计到落地(防查岗神器版)
网络·c++·算法·安全·数据安全·加密
承渊政道30 分钟前
Linux系统学习【Linux系统的进度条实现、版本控制器git和调试器gdb介绍】
linux·开发语言·笔记·git·学习·gitee
JQLvopkk1 小时前
C# 轻量级工业温湿度监控系统(含数据库与源码)
开发语言·数据库·c#
玄同7651 小时前
从 0 到 1:用 Python 开发 MCP 工具,让 AI 智能体拥有 “超能力”
开发语言·人工智能·python·agent·ai编程·mcp·trae