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;
}
相关推荐
程序员泡椒2 小时前
二分查找Go版本实现
数据结构·c++·算法·leetcode·go·二分
瑾修2 小时前
golang查找cpu过高的函数
开发语言·后端·golang
kkkAloha2 小时前
JS笔记汇总
开发语言·javascript·笔记
LawrenceLan8 小时前
Flutter 零基础入门(十一):空安全(Null Safety)基础
开发语言·flutter·dart
txinyu的博客8 小时前
解析业务层的key冲突问题
开发语言·c++·分布式
码不停蹄Zzz8 小时前
C语言第1章
c语言·开发语言
行者969 小时前
Flutter跨平台开发在OpenHarmony上的评分组件实现与优化
开发语言·flutter·harmonyos·鸿蒙
阿蒙Amon9 小时前
C#每日面试题-Array和ArrayList的区别
java·开发语言·c#
SmartRadio9 小时前
ESP32添加修改蓝牙名称和获取蓝牙连接状态的AT命令-完整UART BLE服务功能后的完整`main.c`代码
c语言·开发语言·c++·esp32·ble
且去填词10 小时前
Go 语言的“反叛”——为什么少即是多?
开发语言·后端·面试·go