haraduka's diary

やる気が欲しい

CodeFestival2015本戦 H問題 焼肉の達人

なるほどーなるほどなるほど。
chokudaiさんがトークセッションで言ってたように、やっぱり必ずグラフというのは疑ったほうがいいですね。
これをdpで解こうとしていた自分が悲しくなります。

それにしてもCodeFestival解説がとてもわかりやすいのですべてそちらにお任せしよう…
ほんとうに書いてあるように辺を張ってダイクストラしたら終わりです。ひょえー

template<int MAX_V>
class Dijkstra{
public:
    typedef pair<ll, int> P;
    struct edge{
        int to;
        ll cost;
    };
    const ll INF = 1e18;
    vector<edge> G[MAX_V];
    ll d[MAX_V];
    int V;

    Dijkstra(int v): V(v){}
    Dijkstra(){} //ちゃんとV設定してね

    void add_edge(int from, int to, ll cost){
        G[from].push_back(edge{to, cost});
    }

    void exec(int s){
        priority_queue<P, vector<P>, greater<P> > que;
        fill(d, d+V, INF);
        d[s] = 0;
        que.push(P(0, s));
        while(!que.empty()){
            P p = que.top(); que.pop();
            int v = p.second;
            if(d[v] < p.first) continue;
            for(int i=0; i<(int)G[v].size(); i++){
                edge e = G[v][i];
                if(d[e.to] > d[v] + e.cost){
                    d[e.to] = d[v] + e.cost;
                    que.push(P(d[e.to], e.to));
                }
            }
        }
    }
};

Dijkstra<100010> Dj;

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    int N, M;
    cin >> N >> M;
    P S[N];
    rep(i, N){
        cin >> S[i].first >> S[i].second;
        S[i].second += S[i].first;
    }
    Dj.V = M+1;
    rep(i, M){
        Dj.add_edge(i, i+1, 2);
        Dj.add_edge(i+1, i, 0);
    }
    rep(i, N){
        Dj.add_edge(S[i].first, S[i].second, S[i].second-S[i].first);
    }
    Dj.exec(0);
    cout << 2*M - Dj.d[M] << endl;
}