zoukankan      html  css  js  c++  java
  • poj2686 状压dp入门

    状压dp第一题:很多东西没看懂,慢慢来,状压dp主要运用了位运算,二进制处理

    集合{0,1,2,3,....,n-1}的子集可以用下面的方法编码成整数

    像这样,一些集合运算就可以用如下的方法来操作:

    1.空集....................0

    2.只含有第i个元素的集合{i}................1 << i

    3.含有全部n个元素的集合{0,1,2,3,....,n - 1}.............(1 << n) - 1

    4.判断第i个元素是否属于集合S.................................if(S >> i & 1)

    5.向集合中加入第i个元素S ∪ {i}...............................S | 1 << i

    6.从集合中除去第i个元素S {i}..................................S & ~(1 << i)

    7.集合S和T的并集S∪T...............................................S | T

    8.集合S和T的交集S∩T................................................S & T

    题意:一个人在m个城市的国家旅行,他有n张车票,这个国家有p条路,一条路连接两个城市,他要从a城市到b城市,从一个城市到另一个城市所需要的时间是路的长度除以车票的面值,面值表示可以有多少匹马来拉,求最短的时间。

    题解:看代码,主要就是状压dp+dijkstra

    还有一点就是min只能用于整形,这样的话要算float的话就只能用宏定义了

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<iomanip>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define pi acos(-1)
    #define ll long long
    #define mod 10007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define MIN(a,b) a<b ? a:b
    
    using namespace std;
    
    const double g=10.0,eps=1e-9;
    const int N=9,maxn=30,inf=1<<29;
    
    int n,m,p,a,b,t[maxn];
    int d[maxn][maxn];
    double dp[1<<N][maxn];
    
    void solve()
    {
        for(int i=0;i< 1<<n;i++)//从0到1<<n是所以子集
            fill(dp[i],dp[i]+m,inf);//把dp初始化
        dp[(1<<n)-1][a-1]=0;//起始点设为0,就是dijkstra算法
        double res=inf;
        for(int s=(1<<n)-1;s>=0;s--)
        {
            res=MIN(res,dp[s][b-1]);//记录答案
            for(int v=0;v<m;v++)//起点
                for(int i=0;i<n;i++)//这是车票
                    if(s>>i&1)//判断第i个元素是否属于s
                        for(int u=0;u<m;u++)//终点
                            if(d[v][u]>=0)//使用车票i,从v到u
                                dp[s& ~(1<<i)][u]=MIN(dp[s& ~(1<<i)][u],dp[s][v]+(double)d[v][u]/t[i]);
        }
        if(res==inf)cout<<"Impossible"<<endl;
        else cout<<res<<endl;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout<<setiosflags(ios::fixed)<<setprecision(3);
        while(cin>>n>>m>>p>>a>>b){
            if(!n&&!m)break;
            for(int i=0;i<n;i++)cin>>t[i];
            memset(d,-1,sizeof d);//距离初始化为-1
            for(int i=0;i<p;i++)
            {
                int x,y,z;
                cin>>x>>y>>z;
                x--;
                y--;
                d[x][y]=d[y][x]=z;//保存距离信息,这是无向无环图
            }
            solve();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    思考未来:你的目标是什么
    从非同凡响开始:绝不要做他人也在做的事
    Elasticsearch的内置分词器
    Elasticsearch倒排索引的核心组成
    Session 与 JWT
    vue全屏组件
    css弹性盒骰子
    es6模块化
    移动端适配
    echarts-3D地图
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/6845397.html
Copyright © 2011-2022 走看看