• hdu 4281(MTSP)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4281

    题意:给出N个点,第一个点是裁判,其他N-1个点需要裁判过去回答问题,每个点需要的时间不一样,而每个裁判最多能回答M分钟的问题。题目分两问,第一问是如何分配可以使使用的裁判数最少,第二问是如何分配裁判,使裁判走过的总路程和最少,裁判一开始都在1,最终也要回到1。

    思路:首先我们可以把符合条件的集合预处理出来,然后对于第一问,可以用状态压缩解决,dp[state]表示该状态下的最少裁判数,对于第二问,就是多旅行商问题了,dp[i][j]表示状态为i,在位置j的最小花费,然后开一个best数组来保存最有状态,最后枚举子集,DP合并环即可。比如1~3三个点,裁判在1,那答案就是Min(1->2->3->1,1->2->1 + 1->3->1)。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 #define inf 1<<30
     8 
     9 struct Point{
    10     int x,y;
    11 }point[17];
    12 
    13 int n,m,ans,val[17],dp1[1<<17];
    14 int dp[1<<17][17],best[1<<17];
    15 int Ok[1<<17];
    16 int dist[17][17];
    17 
    18 int Get_Dist(int i,int j)
    19 {
    20     return ceil(sqrt(double(point[i].x-point[j].x)*(point[i].x-point[j].x)+double(point[i].y-point[j].y)*(point[i].y-point[j].y)));
    21 }
    22 
    23 int Judge(int state)
    24 {
    25     int sum=0;
    26     for(int i=0;i<n;i++){
    27         if(state&(1<<i))sum+=val[i];
    28     }
    29     return sum<=m;
    30 }
    31 
    32 int Solve()
    33 {
    34     fill(dp1,dp1+(1<<n),inf);
    35     dp1[0]=0;
    36     for(int state=0;state<(1<<n);state++){
    37         if(Ok[state]){
    38             for(int i=0;i<(1<<n);i++){
    39                 if((state&i)==0&&dp1[i]!=inf){
    40                     dp1[state|i]=min(dp1[state|i],dp1[i]+1);
    41                 }
    42             }
    43         }
    44     }
    45     return dp1[(1<<n)-1];
    46 }
    47 
    48 int TSP()
    49 {
    50     fill(best,best+(1<<n),inf);
    51     for(int i=0;i<(1<<n);i++)
    52         for(int j=0;j<n;j++)dp[i][j]=inf;
    53     dp[1][0]=0;
    54     for(int state=0;state<(1<<n);state++){
    55         if(Ok[state]){
    56             for(int i=0;i<n;i++)if(state&(1<<i)){
    57                 if(dp[state][i]==inf)continue;
    58                 best[state]=min(best[state],dp[state][i]+dist[i][0]);
    59                 for(int j=0;j<n;j++)if(!(state&(1<<j))){
    60                     dp[state|(1<<j)][j]=min(dp[state|(1<<j)][j],dp[state][i]+dist[i][j]);
    61                 }
    62             }
    63         }
    64     }
    65     for(int state=0;state<(1<<n);state++){
    66         if(state&1){
    67             for(int substate=state&(state-1);substate;substate=state&(substate-1)){
    68                 best[state]=min(best[state],best[substate]+best[(state^substate)|1]);
    69             }
    70         }
    71     }
    72     return best[(1<<n)-1];
    73 }
    74 
    75 
    76 int main()
    77 {
    78     while(~scanf("%d%d",&n,&m)){
    79         for(int i=0;i<n;i++)scanf("%d%d",&point[i].x,&point[i].y);
    80         for(int i=0;i<n;i++)scanf("%d",&val[i]);
    81         for(int i=0;i<n;i++)
    82             for(int j=0;j<n;j++)dist[i][j]=Get_Dist(i,j);
    83         for(int s=0;s<(1<<n);s++){
    84             Ok[s]=Judge(s);
    85         }
    86         ans=Solve();
    87         if(ans==inf){
    88             puts("-1 -1");
    89             continue;
    90         }
    91         printf("%d %d
    ",ans,TSP());
    92     }
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    jquery 实现点击图片居住放大缩小
    pycharm git工具与coding.net结合
    Python 小知识点(10)--异常结构记录
    Python 小知识点(9)--反射
    Python 小知识点(8)-- __new__
    @noi.ac
    @noi.ac
    @noi.ac
    @noi.ac
    @游记@ CQOI2019(十二省联考)
  • 原文地址:https://www.cnblogs.com/wally/p/3355940.html
Copyright © 2020-2023  润新知