Traveling by Stagecoach(POJ-2686)(状态压缩DP)

状态压缩DP和普通DP唯一的区别就是它所枚举的对象不再是一个整数,而是一个集合,解决的策略就是利用二进制将这个集合压缩成一个整数。

对于该题,dp[s][v]表示:s表示在该城市剩下的车票集合,v表示在城市v,dp表示在该状态的最小话费。

影响决策的因素有一下几个:

1.一共使用哪几个车票(包括数量和种类)

2.当前从哪个城市到哪个城市

3.使用哪个车票完成两个城市的转移

所以一共需要枚举4个量,用4重循环完成状态转移。

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int max_n = 15;
const int max_m = 35;
const int INF = 1000000;
int n,m,p,a,b,t[max_n],d[max_m][max_m];
double dp[1 << max_n][max_m];
void solve() {
    for(int i=0;i<1<<n;i++){
        fill(dp[i],dp[i]+m,INF);
    }
    dp[(1<<n) - 1][a-1] = 0;
    double res = INF;//用二进制位保存集合,1表示有票,0表示没票
    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){
                    for(int u=0;u<m;u++){
                        if(d[v][u]>=0){
                            dp[s & ~(1<<i)][u] = min(dp[s & ~(1<<i)][u],dp[s][v]+(double)d[v][u]/t[i]);
                        }
                    }
                }
            }
        }
    }
    if(res==INF)  printf("Impossible\n");
    else printf("%.3f\n",res);
}
int main() {
    while(~scanf("%d%d%d%d%d",&n,&m,&p,&a,&b)){
        if(!n&&!m&&!p&&!a&&!b) return 0;
        memset(d,-1,sizeof(d));
        for(int i=0;i<n;i++) scanf("%d",&t[i]);
        for(int i=0;i<p;i++) {
            int q,w,e;
            scanf("%d%d%d",&q,&w,&e);
            q--; w--;
            d[q][w] = d[w][q] = e;
        }
        solve();
    }
    return 0;
}
时间: 2024-11-09 09:33:32

Traveling by Stagecoach(POJ-2686)(状态压缩DP)的相关文章

Mondriaan&#39;s Dream(POJ 2411状态压缩dp)

题意:用1*2的方格填充m*n的方格不能重叠,问有多少种填充方法 分析:dp[i][j]表示i行状态为j时的方案数,对于j,0表示该列竖放(影响下一行的该列),1表示横放成功(影响下一列)或上一列竖放成功.状态转移时,枚举每一行可能的状态上一行取反得下一行能放的状态. #include <map> #include <set> #include <list> #include <cmath> #include <queue> #include &

POJ 3311 状态压缩DP

题意:求从0点走到所有点又走回来的最短距离 该题又很多做法,我用的是弗洛伊德+状态压缩 先遍历所有点,求出两点间最短的距离,而后用状态压缩表示该点是否走过,(1<<n)-1则表示所有点都走过. 附AC代码 #include<stdio.h> #include<string.h> int map[12][12]; int dp[(1<<12)+1][12]; int min1(int a,int b) { if(a<b) return a; return

Traveling by Stagecoach POJ - 2686

Once upon a time, there was a traveler. He plans to travel using stagecoaches (horse wagons). His starting point and destination are fixed, but he cannot determine his route. Your job in this problem is to write a program which determines the route f

poj 3250 状态压缩dp入门

Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7798   Accepted: 4159 Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yumm

poj 2688 状态压缩dp解tsp

题意: 裸的tsp. 分析: 用bfs求出任意两点之间的距离后可以暴搜也可以用next_permutation水,但效率肯定不如状压dp.dp[s][u]表示从0出发访问过s集合中的点,目前在点u走过的最短路程. 代码: //poj 2688 //sep9 #include <iostream> #include <queue> using namespace std; const int maxW=32; const int maxN=12; int dx[4]={-1,1,0,

hdu1143 状态压缩dp 记忆化搜索写法

http://poj.org/problem?id=1143 Description Christine and Matt are playing an exciting game they just invented: the Number Game. The rules of this game are as follows. The players take turns choosing integers greater than 1. First, Christine chooses a

poj2686(Traveling by Stagecoach)状态压缩dp

Description Once upon a time, there was a traveler. He plans to travel using stagecoaches (horse wagons). His starting point and destination are fixed, but he cannot determine his route. Your job in this problem is to write a program which determines

北大ACM2686——Traveling by Stagecoach~~状态压缩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个元素是

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反