关闭

hunnu 11085 count letter tree 树形DP+背包

343人阅读 评论(0) 收藏 举报

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

解题报告(from huzijin)

题目意思:有一棵树,每个节点是由一个带有LevelValue(1~5)的字母组成的。求满足条件的子树的棵数,这些子树满足每棵子树的所有节点的LevelValue值之和等于25
题目特别说明不要求子树的根为字母A
解题思路:
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的儿子的个数。
复杂度:
求解一个状态耗时25次操作,一共有26*26*25种状态。
所以综复杂度为26*26*25*25

#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;
}



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:331113次
    • 积分:6272
    • 等级:
    • 排名:第3932名
    • 原创:308篇
    • 转载:24篇
    • 译文:0篇
    • 评论:46条
    我的微博
    最新评论