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