srm527 T1 && T2

来源:互联网 发布:架构网络直销平台 编辑:程序博客网 时间:2024/04/30 13:39

T1:

problem:

有n个节点,要求构造一棵树,第i个节点的权值为score[degree[i]],degree[i]是节点i的度数。整个树的权值为所有节点权值之和。问树的权值最大为多少。


solution:

显然节点标号是无所谓的,所以就树定向,父亲节点标号小于儿子节点。设fij代表前i - 1个节点处理完了,后面还有j个节点没有父亲。每次枚举当前节点有多少儿子即可转移。


#include <iostream>#include <cstring>#include <algorithm>#include <vector>using namespace std;int f[100][100];class P8XGraphBuilder {public:    int solve(vector <int> scores) {int n = scores.size() + 1;memset(f, -1, sizeof(f));f[1][n - 1] = 0;for (int i = 1; i <= n; ++i)    for (int j = 0; j <= n - i; ++j) if (~f[i][j]) {    f[i + 1][j] = max(f[i + 1][j], f[i][j] + (i != 1 ? scores[0] : 0));    for (int k = 1; k <= j; ++k)f[i + 1][j - k] = max(f[i + 1][j - k], f[i][j] + scores[k - (i == 1)]);}return f[n + 1][0];    }};

T2:

problem:

给定一个带有'?','1','0'的大小为n * m 的矩阵, 再给 m 个长度为 n 的带有'0' '1' '?'的列('?'代表0,1都有可能)。现在要确定矩阵的所有问号,使得m个列的某种排列能和矩阵的所有列对应起来,输出字典序最小的方案。


solution:

如果不要求字典序最小的话,直接二分图匹配即可。要求字典序最小的话,则只要依次枚举每个问号,尝试放0,那么就会删除一些边。如果删完边还能匹配,那么就换成新图(该位置能放0),否则就保留原图(该位置必须放1)。


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <cassert>using namespace std;bool graph[33][33];bool f[33][33], vis[33];int my[33], mt[33];bool find(int x, int n) {    for (int i = 0; i < n; ++i)if (!vis[i] && f[x][i]) {    vis[i] = true;    if (my[i] == -1 || find(my[i], n)) {my[i] = x;return true;    }}    return false;}bool check(int n) {    memset(my, -1, sizeof(my));    int ans = 0;    for (int i = 0; i < n; ++i) {memset(vis, false, sizeof(vis));if (find(i, n)) ++ans;    }    if (ans == n) return true;    return false;}class P8XMatrixRecovery {public:    vector <string> solve(vector <string> rows, vector <string> columns) {int R = rows.size(), C = rows[0].size();memset(graph, false, sizeof(graph));for (int i = 0; i < C; ++i)    for (int j = 0; j < C; ++j) {int k;for (k = 0; k < R; ++k)    if (rows[k][i] != columns[j][k] && rows[k][i] != '?' && columns[j][k] != '?')break;if (k >= R) graph[i][j] = true;    }for (int x = 0; x < R; ++x)    for (int y = 0; y < C; ++y) if (rows[x][y] == '?') {    memcpy(f, graph, sizeof(f));    memset(f[y], false, sizeof(f[y]));    for (int i = 0; i < C; ++i)if (graph[y][i] && columns[i][x] != '1')    f[y][i] = true;    if (check(C)) memcpy(graph, f, sizeof(graph));  }memcpy(f, graph, sizeof(f));assert(check(C));for (int i = 0; i < C; ++i)mt[my[i]] = i;for (int i = 0; i < R; ++i)    for (int j = 0; j < C; ++j) if (rows[i][j] == '?') {    if (columns[mt[j]][i] == '?')rows[i][j] = '0';    else rows[i][j] = columns[mt[j]][i];}return rows;    }};


0 0
原创粉丝点击