Codeforces Round #374 (Div. 2)-C. Journey DP

C. Journey

题意:

在一个DAG(有向无环图)中,问从1 到 n 点,在时间限制K下,最多能游玩几个地点,把游玩的顺序顺便输出。

思路:

感觉dp,一维不够就加一维,我一开始有想到dp,但是只是一维的去推,推着感觉不正确。这次用dp[i][j],表示到j点已游玩i个地点的最少时间。

DAG中一般要想到求拓扑序。即保证dp从左到右。

这题这个人直接两重循环求dp,不知道为啥也是对的 ,确实是有道理,因为dp[ i - 1]这一行的所有情况对于 i 行都是确定的,且i行一定是在i-1行存在的基础上推过来。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <list>
#include <cstdlib>
#include <iterator>
#include <cmath>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <stack>
using namespace std;

#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue

typedef long long ll;
typedef unsigned long long ull;

typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;

#define fi first
#define se second

#define OKC ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A)  //用来压行
#define REP(i , j , k)  for(int i = j ; i <  k ; ++i)

const ll mos = 0x7FFFFFFF;  //2147483647
const ll nmos = 0x80000000;  //-2147483648
const int inf  = 0x3f3f3f3f;
template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<‘0‘||ch>‘9‘) f|=(ch==‘-‘),ch=getchar();
    while (ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
    return x=f?-x:x;
}
// #define _DEBUG;         //*//
#ifdef _DEBUG
freopen("input", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
/*-----------------show time----------------*/

            const int maxn = 5009;
            int dp[maxn][maxn];
            int pre[maxn][maxn];
            int n,m,k;
            struct node
            {
                int u,v,w;
            }e[maxn];
int main(){
            scanf("%d%d%d", &n, &m, &k);

            for(int i=1; i<=m; i++){
                int u,v,w;
                scanf("%d%d%d", &u,&v,&w);
                e[i].v = v, e[i].w = w;
                e[i].u = u;
            }
            memset(dp,inf,sizeof(dp));
            dp[1][1] = 0;

            for(int i=2; i<=n; i++){
                for(int j=1; j<=m; j++){
                    int u = e[j].u,w = e[j].w;
                    int v = e[j].v;
                    if(dp[i][v] > dp[i-1][u] + w ){
                        dp[i][v] = dp[i-1][u] + w;
                        pre[i][v] = u;
                    }
                }
            }
            int id = -1;
            for(int i=n; i>=1;i--){

                if(dp[i][n]<=k){
                    id = i;
                    break;
                }
            }
            printf("%d\n",id);
            stack<int>s;
            int o = n;
            s.push(o);
            for(int i=id; i>=2; i--){
                s.push(pre[i][o]);
                o = pre[i][o];
            }
            while(!s.empty()){
                printf("%d ",s.top());
                s.pop();
            }

            return 0;
}

CF 721C

原文地址:https://www.cnblogs.com/ckxkexing/p/9344615.html

时间: 2024-10-28 09:59:32

Codeforces Round #374 (Div. 2)-C. Journey DP的相关文章

【Codeforces】Codeforces Round #374 (Div. 2) -- C. Journey (DP)

C. Journey time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard output Recently Irina arrived to one of the most famous cities of Berland — the Berlatov city. There are n showplaces in the city, numbered

Codeforces Round #374 (Div. 2) C. Journey

题解: dfs+dp dp[i][j]表示经过i个点后到达j点的最小花费 在dfs每个点的过程中加个for循环i 注意用 long long MLE 代码: #include<bits/stdc++.h> #define maxn 5010 #define mod 1000000007 #define ll long long #define pb push_back using namespace std; const int INF=1e9+7; struct Edge { int v,n

CF #374 (Div. 2) C. Journey dp

1.CF #374 (Div. 2)    C.  Journey 2.总结:好题,这一道题,WA,MLE,TLE,RE,各种姿势都来了一遍.. 3.题意:有向无环图,找出第1个点到第n个点的一条路径,经过的点数要最多. #include<bits/stdc++.h> #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,

Codeforces Round #374 (Div. 2)解题报告

Problem B: Passwords 题意:给出n个字符串密码,在给出一个正确密码,输密码必须先输入简单的密码,连续输错k次密码会罚时5秒,输一次密码耗时1秒,求可能的最短和最长的耗时.(注意:给出的n个密码可能包含多个正确密码) 思路:略 code: #include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <c

Codeforces Round #374 (div.2)遗憾题合集

C.Journey 读错题目了...不是无向图,结果建错图了(喵第4样例是变成无向就会有环的那种图) 并且这题因为要求路径点尽可能多 其实可以规约为限定路径长的拓扑排序,不一定要用最短路做 #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm>

Codeforces Round #374(div 2)

A B:0.0 C:题意:n个点m条边的DAG图(n,m<=5000),保证没有环且都连通,每个边有边权,求一条1->n的路径,使得经过的点最多,但边权和<=T(T<=10^9) 分析:DAG图一般都能DP解决  f[i][j]表示到了第i个点,已经经过了j个点花费的最少边权,last[i][j]就记录对应的决策  阶段的分割就按照拓扑来,不过要注意刚开始不能只把1放进去,要把1和所有入度为0的点都放进去 最后扫一遍答案 值得一说的是按照题目给的边权范围,f数组是应该开long l

Codeforces Round #139 (Div. 2)C Barcode DP

#include<iostream> #include<cstdio> #include<cstring> using namespace std ; const int maxn = 1010; const int inf = 0x3f3f3f3f ; int dp[maxn][2] ; char str[maxn][maxn] ; int num[maxn]; int sum_b[maxn]; int sum_w[maxn]; int main() { // fre

Codeforces Round #276 (Div. 1)D.Kindergarten DP贪心

D. Kindergarten In a kindergarten, the children are being divided into groups. The teacher put the children in a line and associated each child with his or her integer charisma value. Each child should go to exactly one group. Each group should be a

Codeforces Round #271 (Div. 2) D.Flowers DP

D. Flowers We saw the little game Marmot made for Mole's lunch. Now it's Marmot's dinner time and, as we all know, Marmot eats flowers. At every dinner he eats some red and white flowers. Therefore a dinner can be represented as a sequence of several