首页 > 技术文章 > Running Routes Kattis - runningroutes(区间dp)

Jiaaaaaaaqi 2019-12-02 15:32 原文

Running Routes

\[Time Limit: 12000 ms\quad Memory Limit: 1048576 kB \]

题意

给出一个正 \(n\) 边形,标号顺时针从 \(0\)\(n-1\),现在给出 \(n \times n\) 的矩阵,表示从点 \(i\) 到点 \(j\) 有一条边,现在想要让你从中选出最多的边,满足选出的边严格不相交。

思路

\(dp[i][j]\) 表示顺时针从节点 \(i\) 到节点 \(j\) 内,最多可以选出多少边。注意 \(i\) 可以大于 \(j\),表示 \(i\)\(n-1\)\(0\) 再到 \(j\) 的过程。
那么这段就可以利用区间 \(dp\) 的思想来计算

\[ dp[i][j] = dp[i+1][j-1] + a[i][j]\\ dp[i][j] = max(dp[i][k]+dp[k+1][j]) \]

最后所有的 \(dp[i][i-1]\) 的最大值就是答案。

/*************************************************************** 
	> File Name		: H.cpp
	> Author		: Jiaaaaaaaqi
	> Created Time	: Thu 14 Nov 2019 05:23:41 PM CST
 ***************************************************************/

#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define  lowbit(x)  x & (-x)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  fi         first
#define  se         second
#define  pb         push_back
#define  pii        pair<int, int>

typedef unsigned long long int ull;
typedef long long int ll;
const int    maxn = 5e2 + 10;
const int    maxm = 1e5 + 10;
const ll     mod  = 1e9 + 7;
const ll     INF  = 1e18 + 100;
const int    inf  = 0x3f3f3f3f;
const double pi   = acos(-1.0);
const double eps  = 1e-8;
using namespace std;

int n, m;
int cas, tol, T;

int a[maxn][maxn];
int dp[maxn][maxn];

int get(int x) {
	if(x<1)	x+=n;
	if(x>n)	x-=n;	
	return x;
}

int main() {
	// freopen("in", "r", stdin);
	scanf("%d", &n);
	for(int i=1; i<=n; i++) for(int j=1, x; j<=n; j++) {
		scanf("%d", &a[i][j]);
		dp[i][j] = 0;
	}
	for(int i=1; i<=n; i++)	dp[i][get(i+1)] = a[i][get(i+1)];
	for(int d=3; d<=n; d++) {
		for(int i=1, j=get(i+d-1); i<=n; i++, j=get(j+1)) {
			dp[i][j] = dp[get(i+1)][get(j-1)]+a[i][j];
			for(int x=i; x!=j; x=get(x+1)) {
				dp[i][j] = max(dp[i][j], dp[i][x]+dp[get(x+1)][j]);
			}
		}
	}
	int ans = 0;
	for(int i=1; i<=n; i++)
		ans = max(ans, dp[i][get(i-1)]);
	printf("%d\n", ans);
	return 0;
}

推荐阅读