问题 F: Imputation 树形dp

题目链接:点击查看

问题 F: Imputation

时间限制: 1 Sec  内存限制: 128 MB

题目描述

Leila is a Bioinformatician, interested in studying Bacterial evolution. In one experiment on a special type of Bacteria,she started from a single bacterium, put it on a plate, and monitored the bacterial division, until she obtained a population of k bacteria. During the process, she carefully reported the evolutionary relations between bacteria. Precisely, for each bacterium, she reported its parent bacterium.
In the next step, she extracted DNA sequences of k bacteria in the final population, by NGS technology. Each DNA sequence is represented as a string of length m from the alphabet set { A, T, C, G }.
The NGS technology has a drawback: it produces a lot of missing values. So, there are a lot of unknown characters indicated by ‘?’ in the extracted sequences. Considering the evolutionary relationship between bacteria, Leila wants to impute the missing values. Among all possible imputations, she wants to find the minimum cost imputation from an evolutionary perspective.
The problem is defined as follows. A rooted tree T is given, and for each leaf v of T, a string b v of length m from the character set { A, T, C, G, ? } is given. A transition cost matrix ∆ is also given, where ∆(x, y) (x, y ∈ { A, T, C, G }) represents the cost of a transition from an x character to a y character, from a parent to its child.
A feasible imputation, assigns a string s u of length m from the character set { A, T, C, G } to each vertex u, where for each leaf v of T, sv is equal to b v except for ‘?’ characters in bv . The evolutionary cost of an imputation is defined as the sum of evolutionary costs of all edges. The evolutionary cost of an edge between parent u and child w, is defined as , where su[i] is the i-th character of su.
Leila wants to find a feasible imputation for T, which has the minimum evolutionary cost among all feasible imputations.
The tree T, transition cost matrix ∆, and a string bv for each leaf v are given. You should write a program to compute the minimum evolutionary cost of feasible imputations.

输入

The first line of the input contains an integer n (2 ⩽ n ⩽ 10, 000) denoting the number of vertices of T. The vertices of T are numbered from 1 to n. The root of the tree is numbered 1. The root is never considered as a leaf, even if it has only one child. The next n − 1 lines describe the edges of T; each line contains two endpoints of an edge separated by spaces. 
In the next four lines, the evolutionary cost matrix ∆ is given; each line is for one row of ∆. Rows (corresponding to a parent) and columns (corresponding to a child) of ∆ are ordered to respectively represent characters A, T, C and G. All entries of ∆ are non-negative integers not more than 106 . The next line just contains k, the number of leaves. Finally,each leaf v (its number) and its bv which is a string of size m (1 ⩽ m ⩽ 200) appear in one line.

输出

In one line, print the minimum evolutionary cost of feasible imputations.

样例输入

复制样例数据

3
1 2
1 3
0 3 4 4
4 0 4 4
4 4 2 4
1 1 1 0
2
2 AAC
3 T?C

样例输出

4

题意:给出一个树,每个点都有一个ATCG的字符串,都是从祖先转换下来的,给出没两种字符父亲向孩子转换的花费,只给出叶节点的字符串,?代表不确定,求整棵树的最小花费

题解:树形dp,dp[i][j][k] 表示i节点,在字符串的j位置,字符是k时,传到他所有子代的最小花费,复杂度len * 4 * n * 4

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e4 + 10;
vector <int> v[N];
int n, len, m;
ll change[5][5];
ll dp[10010][210][5];
void dfs(int u, int fa) {
	int to;
	int flag = 0;
	int l = v[u].size();
	for(int i = 0; i < l; i++) {
		to = v[u][i];
		if(to == fa) continue;
		dfs(to, u);
		flag = 1;
	}
	if(!flag) return;
//	cout<<u<<endl;
	
	ll cnt = 0, res = 0, tmp;
	for(int i = 1; i <= len; i++) {
		res = 1e18;
		cnt = 0;
		for(int j = 1; j <= 4; j++) {
			cnt = 0;
			for(int k = 0; 	k < l; k++) {
				to = v[u][k];
				if(to == fa) continue;
				tmp = 1e18;
				for(int l = 1; l <= 4; l++) {
					if(dp[to][i][l] >= 0)
						tmp = min(tmp, dp[to][i][l] + change[j][l]);
				}
				if(dp[to][i][0] == -2)
					tmp = min(tmp, min(min(change[j][1], change[j][2]), min(change[j][3], change[j][4])) );
			//	cout << tmp << endl;
				cnt += tmp;
				
			}
		//	cout<<cnt<<" ";
			dp[u][i][j] = cnt;
			
		}
		//cout<<endl;
		
	}
	
}
int main () {
	scanf("%d", &n);
	int x, y;
	for(int i = 1; i <= n-1; i++) {
		scanf("%d %d", &x, &y);
		v[x].push_back(y);
		v[y].push_back(x);
	}
	for(int i = 1; i <= 4;i++)
		for(int j = 1; j <= 4; j++)
			scanf("%lld", &change[i][j]);
	memset(dp, -1, sizeof(dp)); 
	int id;
	char s[210];
	scanf("%d", &m);
	for(int i = 1; i <= m; i++) {
		scanf("%d", &id);
		scanf("%s", s+1);
		len = strlen(s + 1);
		for(int j = 1; j <= len; j++) {
			if(s[j] == 'A') dp[id][j][1] = 0;
			if(s[j] == 'T') dp[id][j][2] = 0;
			if(s[j] == 'C') dp[id][j][3] = 0;
			if(s[j] == 'G') dp[id][j][4] = 0;
			if(s[j] == '?') dp[id][j][0] = -2;
		}
	}
	dfs(1, 0);
	ll ans = 0;
	for(int i = 1; i <= len; i++)
		ans += min(min(dp[1][i][1], dp[1][i][2]), min(dp[1][i][3], dp[1][i][4]));
	printf("%lld\n", ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/mmk27_word/article/details/89066657