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;
}
相关推荐
XXYBMOOO4 小时前
全面解析 Qt `QMessageBox` 类及其常用方法
开发语言·qt·microsoft
知行合一。。。4 小时前
Python--02--流程控制语句
开发语言·python
朝花不迟暮4 小时前
go的文件操作
开发语言·后端·golang
西西学代码4 小时前
Flutter---类
java·开发语言
夏幻灵4 小时前
ASCII 码的具体含义和作用
c++
码农小卡拉4 小时前
Java多线程:CompletableFuture使用详解(超详细)
java·开发语言·spring boot·python·spring·spring cloud
千里马-horse4 小时前
BigInt
开发语言·bigint·napi·addon
Robot侠4 小时前
从 Python 到 Ollama:将微调后的 Llama-3/Qwen 一键导出为 GGUF
开发语言·python·llama·qwen
刺客-Andy4 小时前
JS中级面试题 50道及答案
开发语言·javascript·ecmascript