# hunnu 11085 count letter tree 树形DP+背包

 Counting Letter Tree Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit users: 14, Accepted users: 13 Problem 11085 : No special judgement Problem description Letter Tree is a kind of tree whose node is a letter from A to Z. For example , the carton below shows a Letter Tree , node A is the root of tree and it has two children node D and node M (we can also say that parent of both node D and node M is node A).  What makes it special is that each node of Letter Tree has its Level Value which is between 1 and 5 . The relationship between a letter and its Level Value are showed in following table.  Now we raise the problem : Given a Letter Tree , can you count the number of subtree that the sum of Level Value of each node in the subtree exactly equals to 25 ? Input The first line in the input contains a single integer T(1<=T<=10), indicating the number of test cases.  Each test case begins with a integer N , means the number of node who has one child or more children in the Letter Tree . Then , there will be N strings and each string is in a separate line. The string s[1...Length] means that all nodes s[2],s[3]...s[Length] are children of node s[1]. The input will guarantee that total number of node in a tree is less or equal than 26 and every node is a letter between A and Z. We assume that the root of Letter Tree is always node A ,but the subtree need not meet the assumption. Output For each test , output the answer after the answer MOD 30011 in a separate line. Sample Input 1 5 ADM DKLJ MC LI CBH Sample Output 2

dp[root][i][k]表示以root为根的前i个儿子形成的子树的LevelValue之和为k的子树的棵数。
value[i]表示节点iLevelValue值。

•dp[i,sonCount_i,c]*dp[root,i-1,k-c]

sonCount_i表示节点i的儿子的个数。

#include<stdio.h>
#include<string.h>
#include<vector>
#include<iostream>
#include<fstream>
using namespace std;
const int MODE=30011,N=27,SUM=25;
int pre[N],val[N];
vector<int> vec[N];
int dp[N][N];
void dfs(int root)
{
int len=vec[root].size();
dp[root][val[root]]=1;
int i,j,k;
for(i=0;i<len;++i)
{
int child=vec[root][i];
dfs(child);
for(k=1;k<=SUM;++k)
pre[k]=dp[root][k];
for(k=SUM;k>=0;--k)
for(j=k;j>=0;--j)
if(dp[child][j])
dp[root][k]=(dp[root][k]+pre[k-j]*dp[child][j])%MODE;
}
}

int main()
{
int t,i,j,n;
char str[27];
for(i=0;i<N;++i)
val[i]=i%5+1;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
while(n--)
{
scanf("%s",str);
j=str[0]-'A';
for(i=1;i<strlen(str);++i)
vec[j].push_back(str[i]-'A');
}
memset(dp,0,sizeof(dp));
dfs(0);
int ans=0;
for(i=0;i<N;++i)
{
ans+=dp[i][SUM];
ans%=MODE;
vec[i].clear();
}
cout<<ans<<endl;
}
return 0;
}



• 本文已收录于以下专栏：

举报原因： 您举报文章：hunnu 11085 count letter tree 树形DP+背包 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)