"URAL 1900" brainwashing Device (preprocessing interval and +DP)
Main topic:
N Cities 1~n, Block I city and I+1 have a road.
The first city to i+1~n each city has passenger traffic, if everyone from i->j, to go through I and J each edge once.
The government decided to shorten the distance of K-roads (1 <= k <= n-1)
For everyone, from I to J, if any road in the middle is shortened, he will be happy.
Ask how many people are happy and then output the shortened road number, number I means i->i+1 this road
Consider dp[i][j] means shortening the edge I, while always shortening the maximum happy value of the J-Bar.
One more precursor to its existence.
This will output the output recursively.
Typical path memory dp,ural This kind of problem is really much ...
But a little disgusting is the transfer. DP[J][L-1]->DP[I][L], the increased happy value is j+1~i these cities, the traffic to the i+1 and back of the city ...
I'm going to accumulate in DP enumeration J, so I just need to record each point I, the traffic to Point J and the future city, and go backwards when you're done.
The code is as follows:
#include <iostream> #include <cmath> #include <vector> #include <cstdlib> #include <cstdio > #include <climits> #include <ctime> #include <cstring> #include <queue> #include <stack&
Gt #include <list> #include <algorithm> #include <map> #include <set> #define LL Long Long #define Pr pair<int,int> #define FREAD (CH) freopen (CH, "R", stdin) #define FWRITE (CH) freopen (CH, "w", stdout) using namespace s
td
const int INF = 0X3F3F3F3F;
const int mod = 1E9+7;
Const double EPS = 1e-8;
const int MAXN = 555;
int DP[2][MAXN][MAXN];
int TR[MAXN][MAXN];
void prt (int u,int k) {if (k = = 0) return;
PRT (dp[0][u][k],k-1);
printf ("%d", u);}
int main () {fread ("in.in");
Fwrite ("");
int n,k,x;
scanf ("%d%d", &n,&k);
for (int i = 1; I <= n; ++i) {for (int j = i+1; J <= N; ++j) scanf ("%d", &tr[i][j]);
for (int j = n-1; j > i;--j) TR[I][J] + = tr[i][j+1];
} memset (Dp,-1,sizeof (DP));
Dp[0][0][0] = 0;
Dp[1][0][0] = 0;
for (int i = 1; i < n; ++i) {int tmp = tr[i][i+1];
Dp[0][i][0] = dp[1][i][0] = 0; for (int l = i-1; l >= 0,--l) {for (int j = 1; j <= K; ++j) {if (dp[
0][L][J-1] = =-1) break;
if (Dp[1][l][j-1]+tmp > Dp[1][i][j]) {dp[0][i][j] = l;
DP[1][I][J] = dp[1][l][j-1]+tmp;
}} tmp + = tr[l][i+1];
}} int id = 1;
for (int i = 1; i < n; ++i) {if (Dp[1][i][k] >= dp[1][id][k]) id = i;
} printf ("%d\n", Dp[1][id][k]);
PRT (ID,K);
return 0; }