Timus Online Judge 1651 Shortest Subchain

题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1651
题目大意:有一条链p,有N个节点,需要你找到一条最短的链q。直接来看第二个条件,链q里面的节点的出现顺序必须和链p相同。其实也就找不出其它的条件了。大意就是经过一个节点两次,那么会形成一个环,在满足第二个条件的情况下把所有的环都去掉就行了。

这道题目已经被放了好几天了,刚开始的时候我并没有什么很好的思路,今天早上剪头发的时候突然想起这道题目,发现是个dp,然后就果断上来敲代码。大概的思路和普通dp差不多,关键是要求打印路径,那就涉及到一个路径还原,刚开始的时候这个路径还原的情况并没有考虑完善,直到wa哭了之后才找出错误的原因。具体怎么实现的我还是show me the code吧。

奉上代码,请多指教。

#include <iostream>
#include <cstdio>
#include <vector>
#include <stack>
#define pii pair<int, int>
#define x first
#define y second
using namespace std;
int main() {
    int N;
    scanf("%d", &N);
    vector<int> vec(N);
    for (int i = 0; i < N; ++i) scanf("%d", &vec[i]);
    
    const int INF = 1e9 + 7;
    vector<int> path(N, 0);
    vector<pii> dp(10001, pii(INF, INF));
    dp[vec[0]] = pii(0, 0);
    for (int i = 1; i < N; ++i) {
        //dp[vec[i]] = min(dp[vec[i]], dp[vec[i - 1]] + 1);
        //在不用路径还原的情况下,原始的dp方程如上所示
        if (dp[vec[i - 1]].x + 1 <= dp[vec[i]].x) {
            dp[vec[i]].x = dp[vec[i - 1]].x + 1;
            path[i] = i - 1;
            dp[vec[i]].y = i - 1;//这里为什么要多加一维y?这是我WA了之后加上的,看看下面的else,想想题目中给出的测试数据就知道了
        }
        else path[i] = dp[vec[i]].y;
    }
    /
    //下面就路径还原,随便什么数据结构来维护都行
    stack<int> ans;
    int e = N - 1;
    while (vec[e] != vec[0]) {
        ans.push(vec[e]);
        e = path[e];
    }
    ans.push(vec[0]);
    while (!ans.empty()) {
        printf("%d ", ans.top());
        ans.pop();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值