hdu4848 求到达每一个点总时间最短(sum[d[i]])。

開始的时候是暴力dfs+剪枝。怎么也不行。后来參考他人思想:

先求出每一个点之间的最短路(这样预处理之后的搜索就能够判重返回了)。截肢还是关键:1最优性剪枝(尽量最优:眼下的状态+估计还有的最小时间>min就return !),2:可行性截肢:假设当前状态+估计状态已经不可行,return。(注意考虑是 continue。还是 return !).以及放的位置!在出口放的效果一般好一些(不在下次循环内部)(理由:若该状态是后面的状态进入的,前面的会dfs到非常深,所以。放在最前面。一起推断下,不行就return 一般比較合理。)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n;int da[35];int d[35];
int a[35][35];
int maxd=0;
const int inf=0x3f3f3f3f;
int minn=inf;
int bit[31];
void dfs(int x,int lev,int sum,int allstate)
{
    if(sum+d[x]*(n-lev)>=minn||d[x]>maxd){return;}
    if(allstate==(bit[n]-1))
     {
        minn=sum;
        return;
     }
     for(int i=2;i<=n;i++)
    {
       if((allstate&bit[i-1])==0&&d[x]+a[x][i]>da[i])
               return;
    }
    for(int i=2;i<=n;i++)
    {
       if((allstate&bit[i-1])==0)
       {
           int f=d[i];
           d[i]=d[x]+a[x][i];
          dfs(i,lev+1,sum+d[i],allstate|bit[i-1]);
           d[i]=f;
       }
    }
    return ;
}
void init()
{
    int td=0;
    da[1]=0x3f3f3f3f-1;
    for(int i=1;i<=n;i++)
        d[i]=inf;
    d[1]=0;
    maxd=0;
    minn=inf;
    for(int i=1;i<=n;i++)                       //之前又犯错!

先枚举过度点!
      for(int j=1;j<=n;j++)
        for(int k=1;k<=n;k++)
           if(a[j][i]+a[i][k]<a[j][k])
               a[j][k]=a[j][i]+a[i][k];
}
int main()
{
    for(int i=0;i<31;i++)
        bit[i]=1<<i;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=n;i++)
         for(int j=1;j<=n;j++)
            scanf("%d",&a[i][j]);
         init();
        for(int i=2;i<=n;i++)
           {
                scanf("%d",&da[i]);
              if(da[i]>maxd)maxd=da[i];
           }
          dfs(1,1,0,1);
          if(minn!=inf)
            printf("%d\n",minn);
          else
            printf("-1\n");
    }
    return 0;
}
时间: 2024-08-03 07:02:43

hdu4848 求到达每一个点总时间最短(sum[d[i]])。的相关文章

hdu4848 求到达每个点总时间最短(sum[d[i]])。

开始的时候是暴力dfs+剪枝,怎么也不行.后来参考他人思想: 先求出每个点之间的最短路(这样预处理之后的搜索就可以判重返回了),截肢还是关键:1最优性剪枝(尽量最优:目前的状态+预计还有的最小时间>min就return !),2:可行性截肢:如果当前状态+预计状态已经不可行,return.(注意考虑是 continue,还是 return !).以及放的位置!在出口放的效果一般好一些(不在下次循环内部)(理由:若该状态是后面的状态进入的,前面的会dfs到很深,所以,放在最前面,一起判断下,不行就

【微软100题】一个台阶总共同拥有n 级,假设一次能够跳1 级,也能够跳2 级,求总共同拥有多少总跳法,并分析算法的时间复杂度

package ms100; /** * 一个台阶总共同拥有n 级,假设一次能够跳1 级.也能够跳2 级,求总共同拥有多少总跳法.并分析算法的时间复杂度 *注: 这道题近期常常出现.包含MicroStrategy 等比較重视算法的公司都曾先后选用过个这道题作为面试题或者笔试题. 首先我们考虑最简单的情况: 假设仅仅有1 级台阶,那显然仅仅有一种跳法. 假设有2 级台阶,那就有两种跳的方法了:一种是分两次跳.每次跳1 级:第二种就是一次跳2 级. 如今我们再来讨论普通情况: 我们把n 级台阶时的跳

一个台阶总共有n 级,如果一次可以跳1 级,也可以跳2 级,求总共有多少总跳法,并分析算法的时间复杂度

package ms100; /** * 一个台阶总共有n 级,如果一次可以跳1 级,也可以跳2 级,求总共有多少总跳法,并分析算法的时间复杂度 *注: 这道题最近经常出现,包括MicroStrategy 等比较重视算法的公司都曾先后选用过个这道题作为面试题或者笔试题. 首先我们考虑最简单的情况: 如果只有1 级台阶,那显然只有一种跳法, 如果有2 级台阶,那就有两种跳的方法了:一种是分两次跳,每次跳1 级:另外一种就是一次跳2 级. 现在我们再来讨论一般情况: 我们把n 级台阶时的跳法看成是n

一种减少索引下载/切换总时间的技巧

现在商户索引下载时14台searcher机器同时下载索引大概要花10-12分钟,然后一组一组(3个分布式锁,5组)切换.假定warmup时间为1分半,所以下载+切换的总时间=10分钟 + 5 * 1.5分钟 = 17.5分钟. 注意到这里3台机器切换时,剩下的机器既不切换也不下载,如果能利用切换时间也做下载,将会省下多组切换时间,最理想是只花费1组切换时间,总时间为10分钟 + 1.5分钟 = 11.5分钟,可以省6.5分钟.一个技巧是使用下载分布式锁,不让14台服务器同时下载,这样就可以做到先

输入6个人的成绩放入到一个一维数组中,然后打印出平均分,最后按成绩 从大到小打印。三个功能(输入是一个函数,求平均分是一个函数,排序是一个 函数)都用函数实现,最后在main方法中调用。

/*5.输入6个人的成绩放入到一个一维数组中,然后打印出平均分,最后按成绩从大到小打印.三个功能(输入是一个函数,求平均分是一个函数,排序是一个函数)都用函数实现,最后在main方法中调用.*/ #include <stdio.h> int inputScore(){ int score; scanf("%d",&score); return score;} double avg(int scores[],int length){ int i,score = 0;

获取当前时间UTC时间的下一个15分钟时间点

ZonedDateTime zdt = ZonedDateTime.now(ZoneOffset.UTC); int now15Minute = zdt.getMinute() / P15MINUTE * P15MINUTE; //instant当前时刻的下一个15分钟时间点 Instant instant = ZonedDateTime .of(zdt.getYear(), zdt.getMonthValue(), zdt.getDayOfMonth(), zdt.getHour(), now

简介(1)-概述、一个简单的时间获取客户程序

1.概述 大多数网络应用划分:客户(client)和服务器(server) 一些复杂的网络应用:异步回调通信,即服务器向客户发起请求消息. 协议栈:应用协议.TCP协议.IP协议.以太网协议 局域网(local area network,LAN),广域网(wide area network,WAN). 路由器是广域网的架构设备. 因特网:当今最大的广域网. POSIX:一种被多数厂商采纳的标准. 2.一个简单的时间获取客户程序 1)创建套接字 socket函数 2)指定服务器的IP地址和端口 s

温故知新,基础复习(一个有序从大到小不重复的数列,任意给出一个sum值,求出数列中所有满足和为sum的数对)

温故知新,基础复习(一个有序从大到小不重复的数列,任意给出一个sum值,求出数列中所有满足和为sum的数对) #include<stdio.h> #include<stdlib.h> void PrintSumNumbers(int Arra[],int ASize,int Sum) { //O(1) if (ASize<2) { printf("The size of the Arra is invalid.\n"); return; } if(Sum&

agruments应用——求出函数参数的总合&amp;&amp;css函数——设置/读取对象的属性&amp;&amp;当前输入框高亮显

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-