【poj3311】Hie With The Pie [状压dp]

传送门

dp[state][i] 状态为state时最后到达点i

先用floyd算出最短路,然后用dp[state][i]=min(dp[state][j],dp[state2][j]+mp[j][i]

 

QAQ血的教训就是要写成(1<<(i+1))-1,不能是1<<(i+1)-1 (我改了一上午

 优先级【高到低】:
第一级:圆括号【()】、下标运算符【[]】、分量运算符的指向结构体成员运算符【->】、结构体成员运算符【.】
第二级:逻辑非运算符【!】、按位取反运算符【~】、自增自减运算符【++ –】、负号运算符【-】、类型转换运算符【(类型)】、指针运算符和取地址运算符【*和&】、长度运算符【sizeof】
第三级:乘法运算符【*】、除法运算符【/】、取余运算符【%】
第四级:加法运算符【+】、减法运算符【-】
第五级:左移动运算符【<<】、右移动运算符【>>】
第六级:关系运算符【< > <= >= 】
第七级:等于运算符【==】、不等于运算符【!=】
第八级:按位与运算符【&】
第九级:按位异或运算符【^】
第十级:按位或运算符【|】
第十一级:逻辑与运算符【&&】
第十二级:逻辑或运算符【||】
第十三级:条件运算符【?:】
第十四级:赋值运算符【= += -= *= /= %= >>= <<.= &= |= ^=】
第十五级:逗号运算符【,】

代码

/*
id:gww
language:
*/
#include<bits/stdc++.h>
using namespace std;
const int N=10+2;
const int inf=0x3f3f3f3f;
int n,mp[N][N];//各地状态 
int dp[1<<N][N];//状态为i时目的地为j的最短时间 

inline int read()  //This is 读入优化 
{
    int x=0,w=0;char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    return w?-x:x;
}

void floyd()
{
    for(int i=0;i<=n;++i)
    for(int j=0;j<=n;++j)
    for(int k=0;k<=n;++k)//计算到各点的最短路 
    mp[i][j]=min(mp[i][k]+mp[k][j],mp[i][j]);
}
 
int main()
{
    memset(dp,inf,sizeof(dp));
    n=read();
    int v=(1<<(n+1))-1;
    for(int i=0;i<=n;++i)
    for(int j=0;j<=n;++j)
    mp[i][j]=read();//i地到j地的时间
    floyd();
    for(int sta=0;sta<=v;++sta)//所有状态 
    {
        for(int i=0;i<=n;++i)//到所有点
        {
            if(sta&(1<<i))//如果经过i点
            {
                if(sta==(1<<i)) dp[sta][i]=mp[0][i];//如果只经过i
                else
                {
                    for(int k=0;k<=n;++k)//中间点 
                    if((sta&(1<<k))&&k!=i)//经过k点 
                    dp[sta][i]=min(dp[sta][i],dp[sta^(1<<i)][k]+mp[k][i]);
                    //在没经过i点的状态中
                }
            } 
         } 
    }
    int ans=inf;
    for(int i=0;i<=n;++i)
    /*{
        printf("%d ",dp[v][i]+mp[i][0]);
    }*/
    ans=min(ans,dp[v][i]+mp[i][0]);
    printf("%d",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/lxyyyy/p/10299770.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值