问题描述: 电路扳上下两端共n个节点。 (i, PI(i))表示从 上端i 到 下端 PI(i)的链接。
set = { (i, PI(i)), i belong [1, n+1)}
求: 在set中选择尽可能多的不想交的链接放入第一层中。
问题解答: DP, 设a[i][j] 表示 目前的最大无关子集。
if i与j不相连。 -- a[i][j] = max(a[i-1][j], a[i][j-1])
if i与j相连。 -- a[i][j] = a[i-1][j-1] + 1
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <iostream> #include <cmath> using namespace std; int main() { const int size = 3; int PI[size + 1]; cout << "input the joint PI " << endl; for(int i = 0; i < size; i++){ cin >> PI[i +1]; } cout << "input PI end" << endl; int a[size+1][size+1] = {0}; /* for(int i = 0; i < size + 1; i++){ for(int j = 0; j < size + 1; j++){ cout << a[i][j] << " "; } cout << endl; } */ for(int i = 1; i < size + 1; i++){ for(int j = 1; j < size + 1; j++){ if(j == PI[i]){ cout << i << " " << j << "connected" << endl; a[i][j] = a[i - 1][j - 1] + 1; } else { a[i][j] = max(a[i - 1][j] , a[i][j - 1]); } } } for(int i = 0; i < size + 1; i++){ for(int j = 0; j < size + 1; j++){ cout << a[i][j] << " "; } cout << endl; } cout << "the result is: " << a[size][size]; return 0; }