数据结构与算法“蓝桥杯”

算法刷题记录:

状态压缩动态规划刷题记录


问题描述

提示:这里描述题目中的问题:

n个人在玩传球游戏,传球之间随意,遍历所有状态,实现整个动态规划过程!
解题思路:压缩动态规划
问题:球传递 开始时球在在n个人中任一位手里, 每次传递 都不传给重复的人 且每次传递有代价,不同人之间传递的代价间没有联系。
求:当球经过所有n个人后,整个过程的最低总代价为多少。

//完整代码  带注释
//#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <iostream>
using namespace std;
#include<queue>
#include <cstring>
const int INF = 0x3f;
int a[20][20];
//一维状态 经历了哪些人的手   二维状态保存 球的哪位手上
int dp[1 << 16][20];
int main() {
	int n, m;
	cin >> n;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> a[i][j];//a[i][j] 从i传到j的代价
		}
	}
	//                                  第i位为1 i
	//初始化状态  开始球可以在任何人手里dp[1 << i][i] = 0; 其他状态无穷大 代价
	memset(dp, 0x3f, sizeof(dp));
	for (int i = 0; i < n; i++) {
		//dp表示 球经过了第i个人的手,现在在 第i个人的手上状态
		dp[1 << i][i] = 0;
	}
	//枚举所有可行的状态
	for (int i = 0; i < (1 << n); i++) {//哪些人手上经过了球 1维状态
		//二维状态:这个球现在在哪个人手上
		for (int j = 0; j < n; j++) {
			//这个人在1维状态里  不存在矛盾
			if (i & (1 << j)) {
				//不冲突 枚举 从j传给k
				for (int k = 0; k < n; k++) {
					//k不能在i集合里面 就是 传给没传过的人手里
					if (!(i & 1 << k)) {
						//状态转移方程 在i的集合里  加上第k位 dp[i | 1 << k][k]
						dp[i | 1 << k][k] = min(dp[i | 1 << k][k], dp[i][j] + a[j][k]);
					}
				}
			}
		}
	}
	//枚举最后球在谁手上  最优解 111111
	int ans = INF;
	for (int i = 0; i < n; i++) {
		ans = min(ans, dp[(1 << n) - 1][i]);
	}
	cout << ans << endl;

	return 0;
}
	
	
输入:
 第一行 n个人  下面n行为传递球的代价
 输入样例
3
-1 2 4
3 -1 5
4 4 -1

输出:一个最小代价值
6
![测试](https://img-blog.csdnimg.cn/c7ccbae1087140648ab190ef31869494.png#pic_center)

# 自述:
第一次写东西
记录代码 为自己以后复习用
@[671](c++自学之路)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值