I'm Attacking the Darkness!题解动态规划DP

3732: I'm Attacking the Darkness!

Submit your solution     Discuss this problem     Best solutions
 
Time Limit: 3000 MS    Memory Limit: 65536 K 


  

Description

Many tabletop role-playing games (RPGs), such as a rather famous one involving dragons and dungeons, require the use of dice to simulate various random events in the game. Unlike most regular board games that use six-sided dice, RPGs typically require the use of several polyhedral dice with 4, 6, 8, 12, or 20 sides. Often times the player is required to make a skill check. This involves rolling a set of dice, adding the individual dice rolls together, and then comparing the sum against a pre-determined target value. If the total dice roll is equal to or greater than the target value, then the skill check is considered successful. When a RPG requires a roll of the dice, it will use a dice notation to indicate how many and what kind of dice to roll. For example, "1d4+2d8" would direct the player to roll three dice, one 4-sided die plus two 8-sided ones, and then to add the results of all three dice rolls together. Sometimes the player is required to add or subtract a modifier (i.e. a constant integer) to the total sum of the dice roll. Using the dice notation, a +3 modifier (i.e. a bonus) might be specified as "1d4+2d8+3", while a negative modifier like -5 (i.e. a penalty) might be specified as "1d4-5+2d8". Note that the faces of each die are numbered starting with 1 and going up to the number of sides, so that every face has a unique number. For example, the faces on a 4 sided die would be numbered 1, 2, 3, and 4. Because failing a skill check usually results in something bad happening to the player's character, it's important to know what the chances are of a particular skill check succeeding. To help in this regard, you decided to write a program that reads in a target value along with a dice roll expression, and then prints the probability of passing that skill check.

Input

Input to this problem will begin with a line containing a single integer N (1 ≤ N ≤ 100) indicating the number of data sets. Each data set consists of a single line of the form "T X", where T (0 ≤ T ≤ 100) is the target value, and X is a string containing the dice notation. X will not contain any spaces. The dice notation X will contain one or more terms separated by either a plus "+" or minus "?" sign. Each term can be either an integer M (1 ≤ M ≤ 10) or an expression of the form "NdS" where N (1 ≤ N ≤ 6) and S is an integer equal to 4, 6, 8, 12, or 20. The total number of dice to roll for any given expression will not exceed 6.

Output

For each data set, print a single line with the probability that the given dice roll will be equal to or higher than the target value T. If the target value cannot be achieved, then print the number zero (0). If the target value can always be achieved with every possible dice roll (e.g. due to modifiers), then print the number one (1). Otherwise, print the probability as a fraction reduced to its lowest terms.

Sample Input

2 7 1d6 7 2d4+1

Sample Output

0 3/8
二维费用01背包计数
状态:
d[i][j]表示使用i个产生数j的方法数
状态转移方程:
d[i][j+k]+=d[i-1][j]
边界:
d[0][0]=1;
代码:
#include<cstdio>
#include<cstring>
#include<cctype>

int gcd(int x,int y)
{return y?gcd(y,x%y):x;}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n=1,v=0,sum=0,x=0,y=0,m,i,j,k,a[205],d[205][205]={0};
        char s[1005]={0};
        scanf("%d%s",&m,s+1);
        s[0]='+';
        for(i=0;s[i];i++)
        {
            if(s[i]=='-')
            {
                i++;
                int tt=0;
                while(isdigit(s[i]))
                {
                    tt*=10;
                    tt+=s[i]-'0';
                    i++;
                }
                m+=tt;
            }            
            if(s[i]=='+')
            {
                i++;
                int tt=0;
                while(isdigit(s[i]))
                {
                    tt*=10;
                    tt+=s[i]-'0';
                    i++;
                }
                if(s[i]=='d')
                {
                    i++;
                    int xx=0;
                    if(isdigit(s[i]))
                        xx=s[i]-'0';
                    if(isdigit(s[i+1]))
                        xx*=10,xx+=s[i+1]-'0';
                    for(j=0;j<tt;j++)
                        a[n++]=xx,v+=xx;
                }
                else
                    m-=tt;
                i--;
            }
        }
        d[0][0]=1;
        for(i=1;i<n;i++)
            for(j=0;j<=v;j++)
                for(k=1;k<=a[i];k++)
                    d[i][j+k]+=d[i-1][j];
        for(i=1;i<=v;i++)
        {
            x+=d[n-1][i];
            if(i>=m)
                y+=d[n-1][i];        
        }
        int tt=gcd(x,y);
        if(x==y)
            puts("1");
        else if(y==0)
            puts("0");
        else
            printf("%d/%d/n",y/tt,x/tt);
    }
}
 
 

你可能感兴趣的:(Integer,Random,input,character,each,output)