zoukankan      html  css  js  c++  java
  • hdu 4435 charge-station

    // 题意 从1出发逛完N个点回到出发点 要在这N个点选择性建设加油站 车每次加满油最多可以行使D米
    // 然后最少要花多少钱才能达到上述要求
    // 注意到 第i个城市的花费是 2^(i-1) 所以 我就从N枚举到2
    // 尽量让 i大的不建加油站 应为前i-1个加油站总费用都没有第i个加油站一个的费用多
    // 难点是怎么判断一组方案的可行性
    // 注意到 若i 不建加油站 那么必须存在某个加油站和他距离等于小于 (D+1)/2
    // 这样对于每组方案进行搜索,看下是否每个点都是可以达到并可以回到起点的
    //
    #include <iostream> #include <stdio.h> #include <string.h> #include <cmath> using namespace std; #define INF 100000000 bool mark[200]; int dis[200][200]; int N,D; double sq(double x1,double y1,double x2,double y2){ return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); } bool visit[150]; int ct; void dfs(int u){// 判断有无解
    visit[u]
    =true; ct++; for(int i=1;i<=N;i++) if(!visit[i]&&dis[u][i]<=D){ dfs(i); } } void OK(int u,int lt){// 判断方案的可行性
    if(mark[u]){ lt=D,visit[u]=true; ct++; } else{ if(lt>=(D+1)/2) visit[u]=true,ct++; else return; } for(int i=1;i<=N;i++) if(u!=i&&!visit[i]&&dis[u][i]<=lt) OK(i,lt-dis[u][i]); } int main(){ int rc[200][2]; int i,j; while(scanf("%d %d",&N,&D)!=EOF){ for(i=1;i<=N;i++) mark[i]=true; for(i=1;i<=N;i++) scanf("%d %d",&rc[i][0],&rc[i][1]); if(N==1){printf("0 ");continue;} for(i=1;i<N;i++) for(j=i+1;j<=N;j++){ double t=sq(rc[i][0],rc[i][1],rc[j][0],rc[j][1]); int ti=ceil(sqrt(t)); dis[i][j]=dis[j][i]=ti; } memset(visit,0,sizeof(visit)); ct=0; dfs(1); if(ct<N) {printf("-1 ");continue;} for(i=N;i>1;i--){ // 枚举方案
    mark[i]
    =false; ct=0; memset(visit,0,sizeof(visit)); OK(1,0); if(ct<N) mark[i]=true; } for(i=N;i>0;i--)if(mark[i]) break; for(;i>0;i--) if(mark[i])printf("1");else printf("0"); printf(" "); } return 0; }
  • 相关阅读:
    最长公共子序列问题LCS
    [LuoguP2900] [USACO08MAR]土地征用(Land Acquisition)
    [LuoguP3195] [HNOI2008]玩具装箱TOY
    $Yeasion$的码风修改历程
    点分治模板
    Poj2919 Crane
    Poj2010 Moo University
    Kuhn-Munkres算法
    Uva10791 Minimum Sum LCM
    P1018 乘积最大(高精度加/乘)
  • 原文地址:https://www.cnblogs.com/372465774y/p/3232655.html
Copyright © 2011-2022 走看看