Atcoder 318 D - General Weighted Max Matching

Atcoder 318 D - General Weighted Max Matching_第1张图片Atcoder 318 D - General Weighted Max Matching_第2张图片

Sample Input 1Copy

Copy

4
1 5 4
7 8
6

Sample Output 1Copy

Copy

13

If you choose the edge connecting vertices 11 and 33, and the edge connecting vertices 22 and 44, the total weight of the edges is 5+8=135+8=13.

It can be shown that this is the maximum achievable value.


Sample Input 2Copy

Copy

3
1 2
3

Sample Output 2Copy

Copy

3

�N can be odd.


Sample Input 3Copy

Copy

16
5 6 5 2 1 7 9 7 2 5 5 2 4 7 6
8 7 7 9 8 1 9 6 10 8 8 6 10 3
10 5 8 1 10 7 8 4 8 6 5 1 10
7 4 1 4 5 4 5 10 1 5 1 2
2 9 9 7 6 2 2 8 3 5 2
9 10 3 1 1 2 10 7 7 5
10 6 1 8 9 3 2 4 2
10 10 8 9 2 10 7 9
5 8 8 7 5 8 2
4 2 2 6 8 3
2 7 3 10 3
5 7 10 3
8 5 7
9 1
4

Sample Output 3Copy

Copy

75

 

题目大意:输入的每一个数都有坐标(x,y),选的数的坐标要成对不同,什么意思呢?

(2,3)和(1,4)就是成对不同,而(2,3)和(1,2)就不行。简而言之,坐标的数字不能重复出现

方法1:dfs

分析:这题有点像八皇后,所以用dfs。

因为x和y不能重复出现,说明每行最多只能选一个,多选就会重复。

所以我们可以一行一行地选,当前行可以选一个或者当前行不选(因为每选一个,后续能选的数字就会变少,所以当前行不选,有可能结果更大)。每选一个数都要将其x和y在check数组标记(记得要有回溯还原的操作)

#define inf 0x3f3f3f3f
#define int long long
const int N = 300030;
//#include 
typedef long long ll;
#include
using namespace std;

long long MAX(long long a, long long b) { return a < b ? b : a; }

int a[20][20];
int check[20];
int ans = -1;
int n;
void dfs(int row, int cur) {
	//选到第几行了。当前和
	ans = max(ans, cur);
	if (row < n - 1) {
		//不选当前行的数字,去下一行选的情况
		dfs(row + 1, cur);
	}
	

	for (int i = row + 1; i <= n; i++) {
		if (check[row] == 0 && check[i] == 0) {
			check[row] = 1, check[i] = 1;
			dfs(row + 1, cur + a[row][i]);
			check[row] = 0, check[i] = 0;
		}
	}

	

}
signed main()
{
	cin >> n;
	for (int i = 1; i < n; i++) {
		for (int j = i + 1; j <= n; j++) {
			cin >> a[i][j];
		}
	}
	dfs(1, 0);
	cout << ans;
	return 0;
}


方法2:dp

你可能感兴趣的:(深度优先,算法)