hdu1224 dp(dp + 栈/父亲数组记录路径)

题意:给定 n 个城市的有趣度,并给出可以从那些城市飞到那些城市。其中第一个城市即起始城市同样也作为终点城市,有趣度为 0,旅行途中只允许按有趣度从低到高旅行,问旅行的有趣度最大是多少,并输出旅行路径。

我一开始读题的时候各种深井冰理解错想复杂,导致我一开始甚至认为第一个有趣度 0 代表的是第二个城市,因为第一个城市一定是 0 不需要给出,加上没看到题意里的第一个城市也是第 n + 1 个城市,觉得给出的能旅行的城市里出现了 n + 1 是应该的。还有关于城市联通,我以为给出的联通关系不一定就是按大小排列过后的,然后我还自行按有趣度高低排序之后再放入邻接矩阵。总之就是各种坑爹脑残各种蠢吧……

后来敲完之后各种 WA ,各种比较题解,才发现了各种情况……修修改改 WA 四发之后终于 AC ,输出整个路径我看见大部分题解上用的都是 father 数组,昂,我觉得我还是多珍惜下用栈的机会咯

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<stack>
 5 using namespace std;
 6
 7 struct city{
 8     int v,l;
 9 }c[101];
10 /*
11 bool cmp(city c1,city c2){
12     return c1.v<c2.v;
13 }
14 */
15 bool g[101][101];
16 int dp[101];
17
18 int main(){
19     int T;
20     while(scanf("%d",&T)!=EOF){
21         for(int q=1;q<=T;q++){
22             memset(g,0,sizeof(g));
23             memset(dp,0,sizeof(dp));
24             int n,m,i,j;
25             scanf("%d",&n);
26             for(i=1;i<=n;i++){
27                 scanf("%d",&c[i].v);
28                 c[i].l=-1;
29             }
30             c[1].l=1;
31             scanf("%d",&m);
32             for(i=1;i<=m;i++){
33                 int a,b;
34                 scanf("%d%d",&a,&b);
35                 if(b==n+1)g[a][1]=1;
36                 else g[a][b]=1;
37             }
38             int ans=0,t=1;
39
40             for(i=2;i<=n;i++){
41                 for(j=1;j<i;j++){
42                     if(g[j][i]&&((dp[j]+c[i].v)>dp[i])){
43                         dp[i]=dp[j]+c[i].v;
44                         c[i].l=j;
45                         if(g[i][1]&&dp[i]>ans){
46                             ans=dp[i];
47                             t=i;
48                         }
49                     }
50                 }
51             }
52             printf("CASE %d#\npoints : %d\ncircuit : ",q,ans);
53             stack<int>S;
54             int tmp=t;
55             while(!S.empty()){
56                 S.pop();
57             }
58             S.push(1);
59             while(c[tmp].l!=tmp){
60                 S.push(tmp);
61                 tmp=c[tmp].l;
62             }
63             printf("1");
64             while(!S.empty()){
65                 tmp=S.top();
66                 S.pop();
67                 printf("->%d",tmp);
68             }
69             printf("\n");
70             if(q!=T)printf("\n");
71         }
72     }
73     return 0;
74 }

时间: 2024-11-11 14:48:50

hdu1224 dp(dp + 栈/父亲数组记录路径)的相关文章

【DP】UVA 624 CD 记录路径

开一个数组p 若dp[i-1][j]<dp[i-1][j-a[i]]+a[i]时就记录下p[j]=a[i];表示此时放进一个轨道 递归输出p #include <stdio.h> #include <string.h> #include <stdlib.h> #include <limits.h> #include <malloc.h> #include <ctype.h> #include <math.h> #in

poj1416——dfs递归枚举+记录路径

POJ 1416  dfs递归枚举+记录路径 Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4456   Accepted: 2555 Description You have just been put in charge of developing a new shredder for the Shredding Company Although a "normal" s

最短路 + 记录路径 之 zoj 1456 Minimum Transport Cost (hdu 1385)

/* 考虑到测试数据中需要求解任意两点间的最短路,所以采用Floyd-Warshall算法 dp[i][j] = min(dp[i][k] + dp[k][j] + tax[k], dp[i][j]); 关键在于记录路径,并且要保证:if there are more minimal paths, output the lexically smallest one. 分两种情况讨论: (1)dp[i][j] > dp[i][k] + dp[k][j] + tax[k] 直接更新dp[i][j],

Charlie&#39;s Change POJ - 1787 (完全背包+记录路径)

完全背包输出路径:对于每一次更新记录一下路径:注意钱币个数: dp[i][0]代表在空间为i时需要多少枚钱币 dp[i][1]用来记录路径 cheek[j]用来记录在j时用了多少i枚钱币 思路在代码中: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define mem(a,b) memset(a,b,sizeof

hdu1074 状压DP、栈实现记录路径

题意:给了几门学科作业.它们的截止提交期限(天数).它们的需要完成的时间(天数),每项作业在截止日期后每拖延一天扣一学分,算最少扣的学分和其完成顺序. 一开始做的时候,只是听说过状态压缩这个神奇的东西,但事实上我并不会用它,所以白白想了一个晚上没想出来,然后就看了一下题解```再见吧朋友又是新的算法要学了. 状态压缩,实际上就是用二进制的方式,对于每一个要考察的状态用0/1表示其完成与否,这样当从 1 遍历到 111```111 的时候,就可以遍历完所有的状态了,在遍历的过程中利用位运算以及状态

zoj 3812 We Need Medicine (dp 位优化 巧妙记录路径)

We Need Medicine Time Limit: 10 Seconds      Memory Limit: 65536 KB      Special Judge A terrible disease broke out! The disease was caused by a new type of virus, which will lead to lethal lymphoedema symptom. For convenience, it was namedLL virus.

UVA 624 CD 记录路径DP

开一个数组p 若dp[i-1][j]<dp[i-1][j-a[i]]+a[i]时就记录下p[j]=a[i];表示此时放进一个轨道 递归输出p #include <stdio.h> #include <string.h> #include <stdlib.h> #include <limits.h> #include <malloc.h> #include <ctype.h> #include <math.h> #in

URAL 1244 Gentlement DP +记录路径 好题

1244. Gentlemen Time limit: 0.5 secondMemory limit: 64 MB Let's remember one old joke: Once a gentleman said to another gentleman:— What if we play cards?— You know, I haven't played cards for ten years…— And I haven't played for fifteen years…So, li

POJ 1141 Brackets Sequence (区间dp 记录路径)

题目大意: 给出一种不合法的括号序列,要求构造出一种合法的序列,使得填充的括号最少. 思路分析: 如果只要求输出最少的匹配括号的数量,那么就是简单的区间dp dp[i][j]表示 i - j 之间已经合法了最少添加的括号数. 转移 就是 dp[i] [j] = min  (dp[i+1][j]+1 , dp[ i+ 1] [ k -1 ] + dp[k+1] [j] (i k 位置的括号匹配)) 其次我们要记录路径,你发现  如果 dp [i] [j] 是由 dp [i+1] [j] 转移过来的