- 著者:zifeiy
- タグ:動的計画、最短パス
リンクタイトル:https://www.luogu.org/problem/P1280
タイトル効果:
n個の時刻nに最初にk個のタスクの分布と、最初にi番目のタスク\(P_I \)は分を開始し、持続\(T_I \)分、タスクが最初であろう(P_I + T_I-1 \) \ エンド分。
あなたは私のアイドル時間が、今回私は開始時に少なくとも一つのタスクがあるしている場合は、あなたがしたいタスクを選択する必要があります。
あなたが自由である私の瞬間あれば、一度にいずれかのタスクなし私は開始、その後、あなたは私がアイドル状態の瞬間にすることができます。
無料で何時間、最もあなたを請います。
ダイナミックプログラミングソリューション
私たちは、作る([i]は\ F)\時間nの終わりのこの時間の間にアイドル時間の最大数に瞬間私から始まります。
その後、我々は、私は時間にn個の時間に1から私を反復処理することができます。
- 何の仕事は、私は、その後の時間で開始されていない場合は、\(Fは、[i]は= F + 1 \ [I + 1]) ;
- そうでなければ\(F [I]は= \ MAX(F)\ [IはT_J +]) 、ここで、\(T_J \)全てに対応する\(I P_j == \)を。
次のようにコードは次のとおりです。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;
int n, k, p, t, f[maxn];
vector<int> g[maxn];
int main() {
cin >> n >> k;
while (k --) {
cin >> p >> t;
g[p].push_back(t);
}
for (int i = n; i >= 0; i --) {
int sz = g[i].size();
if (sz == 0) f[i] = f[i+1] + 1;
else {
for (int j = 0; j < sz; j ++)
f[i] = max(f[i], f[ i + g[i][j] ]);
}
}
cout << f[1] << endl;
return 0;
}
最短ソリューション
このアイデアブログtong_xzギャング
図中の点として時点。
最初の分、P + T Tも右側ではない点に点からみなす期間T P分タスクからP。(出発点は、タスクの開始エッジ時間で、最後には、次の分のミッション時間の終わりである)
最後のポイントは、学位を持っていなかった場合は、右側のも、背面側点が行うには、ゼロ(仕事、この何もありません分、彼は魚をキャッチすることができます...)
乾燥させるために、少なくともどのくらい彼を得るために最短経路を実行するために、答えは(N-最短結果である)
最長の道路との言葉の他の部分と右端が行うことができます。
次のようにコードは次のとおりです。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;
int in[maxn], out[maxn], n, k, p, t, dis[maxn];
bool vis[maxn];
vector< pair<int, int> > g[maxn];
queue<int> que;
void spfa() {
memset(dis, -1, sizeof(int) * (n+2));
dis[1] = 0;
que.push(1);
while (!que.empty()) {
int u = que.front();
que.pop();
vis[u] = false;
int sz = g[u].size();
for (int i = 0; i < sz; i ++) {
int v = g[u][i].first, w = g[u][i].second;
if (dis[v] == -1 || dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
if (!vis[v]) {
vis[v] = true;
que.push(v);
}
}
}
}
}
int main() {
cin >> n >> k;
while (k --) {
cin >> p >> t;
out[p] ++;
in[p+t] ++;
g[p].push_back(make_pair(p+t, t));
}
for (int i = 1; i <= n; i ++) {
if (!out[i]) g[i].push_back(make_pair(i+1, 0));
}
spfa();
cout << n - dis[n+1] << endl;
return 0;
}