您的位置:首页 > 其它

Vijos 1456 最小总代价(状态压缩DP)

2013-03-13 10:57 471 查看
题目链接

用二维数组表示,第一维表示状态,第二维表示此状态最后一个专递者。

状态转移为 if((~que1[j])&(1<<u))//开始这个判断想错了,一直RE。。。对位运算不熟啊。。

dp[que1[j]+(1<<u)][u] = min(dp[que1[j]+(1<<u)][u],dp[que1[j]][k]+p[k+1][u+1]);

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
using namespace std;
#define INF 0x3f3f3f3f
int p[20][20];
int dp[500000][17];
int que1[500000],que2[500000];
int o[500000];
int main()
{
int n,i,j,k,u,num,t;
scanf("%d",&n);
for(i = 1; i <= n; i ++)
{
for(j = 1; j <= n; j ++)
scanf("%d",&p[i][j]);
}
for(i = 0; i < 1<<n; i ++)
{
for(j = 0; j < n; j ++)
{
dp[i][j] = INF;
}
}
num = 0;
for(i = 0; i < n;i ++)
{
dp[1<<i][i] = 0;
que1[num++] = 1<<i;
}
for(i = 2;i <= n;i ++)
{
t = 0;
for(j = 0;j < num;j ++)
{
for(k = 0;k < n;k ++)
{
for(u = 0;u < n;u ++)
{
if(k != u)
{
if((~que1[j])&(1<<u))
{
dp[que1[j]+(1<<u)][u] = min(dp[que1[j]+(1<<u)][u],dp[que1[j]][k]+p[k+1][u+1]);
if(!o[que1[j]+(1<<u)])
{
o[que1[j]+(1<<u)] = 1;
que2[t++] = que1[j]+(1<<u);
}
}
}
}
}
}
num = t;
for(j = 0;j < num;j ++)
{
que1[j] = que2[j];
que2[j] = 0;
}
}
int ans = INF;
for(i = 0;i < n;i ++)
ans = min(dp[(1<<n)-1][i],ans);
printf("%d\n",ans);
return 0;
}
/*
16
-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: