zoukankan      html  css  js  c++  java
  • hdu--4571--最短路+dp

    这题 不会写啊 虽然题意明白了 方法大概知道 但是状态有点难表示啊 啊 啊...

    放个 题解链接 大概看懂了  主要是dp初始化没想到 自己一般都只是个Memset之后  就是对于1 2个点的特别初始化了  没有想到过对于其它所有点的状态表示就是1-n的

          传送

    代码 放出来 方便看.~

      1 #include<iostream>
      2 #include<cmath>
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<string>
      6 #include<cstring>
      7 #include<algorithm>
      8 #include<vector>
      9 #include<map>
     10 #include<set>
     11 #include<stack>
     12 #include<list>
     13 #include<queue>
     14 #define eps 1e-6
     15 #define INF 0x1f1f1f1f
     16 #define PI acos(-1.0)
     17 #define ll __int64
     18 #define lson l,m,(rt<<1)
     19 #define rson m+1,r,(rt<<1)|1
     20 //#pragma comment(linker, "/STACK:1024000000,1024000000")
     21 using namespace std;
     22 
     23 /*
     24 freopen("data.in","r",stdin);
     25 freopen("data.out","w",stdout);
     26 */
     27 #define Maxn 110
     28 int dp[Maxn][310]; //dp[i][j]表示到达第i个点花了j时间的能获得的最大满意度
     29 int dis[Maxn][Maxn]; //任意两点间的距离
     30 int n,m;
     31 
     32 struct Node
     33 {
     34    int id,si,ci;
     35    friend bool operator < (const struct Node &a,const struct Node &b)
     36    {
     37       return a.si<b.si; //按满意度从小到大排序
     38    }
     39 }node[Maxn];
     40 
     41 void floy()
     42 {
     43    for(int i=0;i<n;i++)
     44       for(int j=0;j<n;j++)
     45       {
     46          if(i==j)
     47             dis[i][j]=0; //不游玩的到达时间
     48          else
     49             dis[i][j]=INF;
     50       }
     51    int a,b,v;
     52    for(int i=0;i<m;i++)
     53    {
     54       scanf("%d%d%d",&a,&b,&v); //注意有重边
     55       dis[a][b]=dis[b][a]=min(dis[a][b],v);
     56    }
     57 
     58    for(int k=0;k<n;k++) //floyd 不断更新两点间的距离
     59       for(int i=0;i<n;i++)
     60          for(int j=0;j<n;j++)
     61          {
     62             dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
     63          }
     64    return ;
     65 }
     66 
     67 int main()
     68 {
     69    int tt,s,e,t;
     70    int ca=0;
     71 
     72    scanf("%d",&tt);
     73    while(tt--)
     74    //while(~scanf("%d%d%d%d%d",&n,&m,&t,&s,&e))
     75    {
     76       scanf("%d%d%d%d%d",&n,&m,&t,&s,&e);
     77       for(int i=0;i<n;i++)
     78       {
     79          scanf("%d",&node[i].ci);
     80          node[i].id=i;
     81       }
     82       for(int i=0;i<n;i++)
     83          scanf("%d",&node[i].si);
     84       sort(node,node+n);
     85       floy();
     86 
     87       printf("Case #%d:
    ",++ca);
     88       if(dis[s][e]>t) //起点不能到达终点或到达时间超过了
     89       {
     90          puts("0");
     91          continue;
     92       }
     93       memset(dp,-1,sizeof(dp));
     94       int ans=0;
     95       for(int i=0;i<n;i++) //初始化
     96       {
     97          if(dis[s][node[i].id]+node[i].ci<=t)
     98          {
     99             dp[node[i].id][node[i].ci+dis[s][node[i].id]]=node[i].si;
    100            // dp[node[i].id][dis[node[s].id][node[i].id]]=0;
    101          }
    102          if(t-dis[s][node[i].id]-node[i].ci>=dis[node[i].id][e])
    103             ans=max(ans,node[i].si);
    104       }
    105 
    106       for(int i=1;i<n;i++)
    107          for(int j=t;j>=0;j--)
    108          {
    109             for(int k=0;k<i;k++)
    110             {
    111                int tmp=j-node[i].ci-dis[node[k].id][node[i].id]; //注意是严格大于
    112                if(tmp>=0&&node[i].si>node[k].si&&dp[node[k].id][tmp]!=-1)
    113                   dp[node[i].id][j]=max(dp[node[i].id][j],dp[node[k].id][tmp]+node[i].si);
    114             }
    115             if(t-j>=dis[node[i].id][e]) //该点的所有时间都求完了
    116                ans=max(ans,dp[node[i].id][j]);
    117          }
    118       printf("%d
    ",ans);
    119    }
    120    return 0;
    121 }
    View Code

     /*******/

    洗个澡 想明白了很多 .-大致说下步骤

    首先 floyd预处理任意两个点间的最短距离   然后就是最重要的 for遍历所有城市节点  初始化从该S点出发到该点的dp[][]状态

    这边 主要是初始化. 所以其实

    1       for(int i=0;i<n;i++) //初始化
    2       {
    3          if(dis[s][node[i].id]+node[i].ci<=t)
    4          {
    5             dp[node[i].id][node[i].ci+dis[s][node[i].id]]=node[i].si;
    6          }
    7          //if(t-dis[s][node[i].id]-node[i].ci>=dis[node[i].id][e])
    8          //   ans=max(ans,node[i].si);
    9       }

    我注释的 这两行是可以省去的 <如果我没理解错的话>

    然后 接下去 就是一个很重要的 3层遍历了

    因为我们在初始化之前就已经sort好了 让城市是按照满意程度从小到大排序的  所以我们肯定是从1 - n递推的

    然后 注意时间是要 递减的 这就和01背包中 体积逆序遍历一个道理 物品<景点>只能取一次

    //////////////////////////////////

    总的来说 这题 很好!!!!!

    today:

      think and think

      believe youselft 

      just jj =_=

  • 相关阅读:
    Ant Design Pro:Layout 组件——嵌套布局
    React实战之将数据库返回的时间转换为几分钟前、几小时前、几天前的形式。
    React实战之Ant Design—Upload上传_附件上传
    React实战之60s倒计时按钮(发送短信验证按钮)
    map方法到底会不会改变原始数组?
    【React】react开发vscode插件推荐
    【React】React 工程的 VS Code 插件及配置
    【React】react新特性实例详解(memo、lazy、suspense、hooks)
    数组常用slice和splice的区别
    【React】react-beautiful-dnd 实现组件拖拽
  • 原文地址:https://www.cnblogs.com/radical/p/4104403.html
Copyright © 2011-2022 走看看