zoukankan      html  css  js  c++  java
  • POJ1694 An Old Stone Game

    POJ1694 An Old Stone Game
    Time Limit: 1000MS Memory Limit: 10000K
    Total Submissions: 2579 Accepted: 1137

    Description

    There is an old stone game, played on an arbitrary general tree T. The goal is to put one stone on the root of T observing the following rules: 
    1. At the beginning of the game, the player picks K stones and puts them all in one bucket. 
    2. At each step of the game, the player can pick one stone from the bucket and put it on any empty leaf. 
    3. When all of the r immediate children of a node p each has one stone, the player may remove all of these r stones, and put one of the stones on p. The other r - 1 stones are put back into the bucket, and can be used in the later steps of the game.

    The player wins the game if by following the above rules, he succeeds to put one stone on the root of the tree. 
    You are to write a program to determine the least number of stones to be picked at the beginning of the game (K), so that the player can win the game on the given input tree. 

    Input

    The input describes several trees. The first line of this file is M, the number of trees (1 <= M <= 10). Description of these M trees comes next in the file. Each tree has N < 200 nodes, labeled 1, 2, ... N, and each node can have any possible number of children. Root has label 1. Description of each tree starts with N in a separate line. The following N lines describe the children of all nodes in order of their labels. Each line starts with a number p (1 <= p <= N, the label of one of the nodes), r the number of the immediate children of p, and then the labels of these r children.

    Output

    One line for each input tree showing the minimum number of stones to be picked in step 1 above, in order to win the game on that input tree.

    Sample Input

    2
    7
    1 2 2 3
    2 2 5 4
    3 2 6 7
    4 0
    5 0
    6 0
    7 0
    12
    1 3 2 3 4
    2 0
    3 2 5 6
    4 3 7 8 9
    5 3 10 11 12
    6 0
    7 0
    8 0
    9 0
    10 0
    11 0
    12 0
    

    Sample Output

    3
    4
    

    Source

    **********************************************************************
    题目大意:在一棵树上面放石头,必须先放满一个节点的儿子才能才这个节点上放石头,当该节点的儿子都放满了,就可以把这些石头放回篮子,然后把一个石头放在这个节点上。问,要放到根节点最少需要多少个石头。
    解题思路:第一次看到这道题目是在一次水水的比赛中,当时纠结了半天也没做出来。现在才想得通是树形dp。
    要在一个节点上放石头,所需的最少的石头数,是跟他儿子有直接的关系。
    首先,如果这个节点是叶子节点,那么dp[s]=1;
    如果这个节点不是叶子节点,那么就需要模拟一下:首先取出它儿子中dp[t]最大的那个点,那么dp[s]的起始点就是dp[t],然后模拟篮子中还剩几个石头。把儿子都模拟出来就好了。
    #include <stdio.h>
    #include <string.h>
    #include <vector>
    #include <queue>
    #define N 205
    using namespace std;
    
    vector<int>gra[N];
    int dp[N],n;
    
    void dfs(int s)
    {
        priority_queue<int>que;
        for(int i=0;i<gra[s].size();i++)
        {
            int t=gra[s][i];
            dfs(t);
            que.push(dp[t]);
        }
        if(gra[s].size()==0)
        {
            dp[s]=1;
            return ;
        }
        int sum=que.top(),temp=sum-1;
        que.pop();
        while(que.empty()==0)
        {
            int t=que.top();
            que.pop();
            if(temp>=t)
                temp=temp-1;
            else
                sum+=t-temp,temp=t-1;
        }
        dp[s]=sum;
    }
    
    void re(void)
    {
        scanf("%d",&n);
        for(int i=0;i<=n;i++)
            gra[i].clear();
        for(int i=1;i<=n;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            for(int j=1;j<=b;j++)
            {
                int c;
                scanf("%d",&c);
                gra[a].push_back(c);
            }
        }
    }
    
    void run(void)
    {
        dfs(1);
        printf("%d\n",dp[1]);
    }
    
    int main()
    {
        int ncase;
        scanf("%d",&ncase);
        while(ncase--)
        {
            re();
            run();
        }
    }
    

      

  • 相关阅读:
    6-MySQL-Ubuntu-操作数据表的基本操作(一)
    5-MySQL-Ubuntu-操作数据库的基本操作语句
    11-Ubuntu-根目录下各目录的功能详细介绍
    4-Ubuntu-启动/关闭/重启mysql服务
    3-Windows-CMD启动mysql服务-连接本地mysql服务-连接远程mysql服务
    2-Ubuntu命令安装mysql服务器和客户端及安装后的简单验证操作
    1-Navicat无法远程连接Ubuntu上的MySQL(已解决)
    10-python基础—索引与切片总结
    Useful Things To Know About Machine Learning (机器学习中一些有用的知识)
    How to Use the TimeDistributed Layer for Long Short-Term Memory Networks in Python 译文
  • 原文地址:https://www.cnblogs.com/Fatedayt/p/2195539.html
Copyright © 2011-2022 走看看