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 =_=

原文地址:https://www.cnblogs.com/radical/p/4104403.html