牛客训练五:炫酷路途(c++与dp)

题目链接:传送门

思路:每隔2^i(0<=i<=INF)就有一条路径,所以可以将从头到尾的路线视为一个有向图,

将ai,bi以此输入,然后将路径从小到大排序,不断更新路径。

 __builtin_popcount (unsigned u)函数可以以O(1)的复杂度计算u的二进制中的数字1的个数。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int INF = 999999;
int a[50],b[50],dis[50];
vector <int> vc;
int main(void)
{
    int n,m,i,j,p,k;
    while(~scanf("%d%d",&n,&k)){
        vc.clear();
        for(i=0;i<k;i++){
            scanf("%d%d",&a[i],&b[i]);
            if(a[i]>b[i]) swap(a[i],b[i]);
            vc.push_back(a[i]);
            vc.push_back(b[i]);
        }
        vc.push_back(1);vc.push_back(n);
        sort(vc.begin(),vc.end());
        vc.erase(unique(vc.begin(),vc.end()),vc.end());
        memset(dis,INF,sizeof(dis));
        dis[0]=0;
        int len=vc.size();
        for(i=0;i<len;i++)
            for(j=i+1;j<len;j++){
                for(p=0;p<len;p++)
                if(vc[i]==a[p]&&vc[j]==b[p]){
                    dis[j]=min(dis[i]+1,dis[j]);
                }
                dis[j]=min(dis[j],dis[i]+__builtin_popcount(vc[j]-vc[i]));
            }
        printf("%d\n",dis[len-1]);
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/2018zxy/p/10351206.html