最小总代价Vijos-1456 状态压缩
最小总代价(Vijos-1456)
题目描述:
n个人在做传递物品的游戏,编号为1-n。
游戏规则是这样的:开始时物品可以在任意一人手上,他可把物品传递给其他人中的任意一位;下一个人可以传递给未接过物品的任意一人。
即物品只能经过同一个人一次,而且每次传递过程都有一个代价;不同的人传给不同的人的代价值之间没有联系;
求当物品经过所有n个人后,整个过程的总代价是多少。
输入格式:
第一行为n,表示共有n个人(16>=n>=2);
以下为n*n的矩阵,第i 1行、第j列表示物品从编号为i的人传递到编号为j的人所花费的代价,特别的有第i 1行、第i列为-1(因为物品不能自己传给自己),其他数据均为正整数(<=10000)。
(对于50%的数据,n<=11)。
输出格式:
一个数,为最小的代价总和。
输入样例:
2
-1 9794
2724 –1
输出样例:
2724
算法分析
看到2<=n<=16,应想到此题和状态压缩dp有关。每个人只能够被传递一次,因此使用一个n位二进制数state来表示每个人是否已经被访问过了。但这还不够,因为从这样的状态中,并不能清楚地知道现在物品在谁 的手中,因此,需要在此基础上再增加一个状态now,表示物品在谁的手上。
dp[state][now]表示每个人是否被传递的状态是state,物品在now的手上的时候,最小的总代价。
初始状态:dp[1<<i][i]=0;表示一开始物品在i手中。
所求状态:min(dp[(1<<n)-1][j]); 0<=j<n
状态转移方程:
dp[state][now]=min(dp[pre][t] dist[now][t]);
pre表示的是能够到达state这个状态的一个状态,t能够传递物品给now且只有二进制下第t位与state不同。
状态的大小是O((2n)*n),转移复杂度是O(n)。总的时间复杂度是O((2n)*n*n)。
代码实现
/*
ID:shijieyywd
PROG:Vijos-1456
LANG:c
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define MAXN 20
#define INF 0x3f3f3f3f
using namespace std;
int n;
int edges[MAXN][MAXN];
int dp[65546][MAXN];
int min(int a, int b)
{
if (a == -1) return b;
if (b == -1) return a;
return a < b ? a : b;
}
int main() {
scanf("%d", &n);
int t;
for (int i = 0; i < n; i )
{
for (int j = 0; j < n; j )
{
scanf("%d", &edges[i][j]);
}
}
memset(dp, -1, sizeof(dp)); //初始化
for (int i = 0; i < n; i )
{
dp[1 << i][i] = 0;
}
int ans = -1;
for (int i = 0; i < (1 << n); i ) //状态,二进制所对应的数
{
for (int j = 0; j < n; j ) //物品在第j个人手里
{
if (dp[i][j] != -1)
{
for (int k = 0; k < n; k ) //往k传
{
if (!(i & (1 << k)))
{
dp[i | (1 << k)][k] = min(dp[i | (1 << k)][k], dp[i][j] edges[j][k]); //注意,min是一个自定义函数
//if ((i | (1 << k)) == (1 << n) - 1) ans = min(ans, dp[i | (1 << k)][k]);
}
}
}
}
}
for(int i = 0;i < n;i )
ans = min(dp[(1<<n)-1][i],ans);
if (ans != -1)
printf("%d\n", ans);
else printf("0\n");
return 0;
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhhkjkbe
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
微信运动停用后别人还能看到步数吗
PHP中文网 07-22 -
excel打印预览压线压字怎么办
PHP中文网 06-22