题意:给定n个骰子和一个x,要求出用这些骰子投出大于等于x的概率。要求最简。
分析:先预处理算出i个骰子得到的和为j的种数。然后用gcd函数约分。
dp[i+1][j+k]=sigma(dp[i][j]) (1<=k<=6)
AC代码1:
#include<cstdio> #include<iostream> #include<cstring> typedef unsigned long long ull; using namespace std; __int64 dp[30][155]; __int64 gcd(__int64 x,__int64 y) { return y?gcd(y,x%y):x; } int main() { __int64 up,down,g; int T,n,x,i,j,k; for(i=1;i<=6;i++) dp[1][i]=1; for(i=1;i<25;i++) { for(j=i;j<=6*i;j++) { for(k=1;k<=6;k++) dp[i+1][j+k]+=dp[i][j]; } } scanf("%d",&T); for(int cas=1;cas<=T;cas++) { scanf("%d%d",&n,&x); if(x>n*6) { printf("Case %d: 0\n",cas); continue; } if(x<=n) { printf("Case %d: 1\n",cas); continue; } up=0,down=1; for(i=x;i<=n*6;i++) up+=dp[n][i]; for(j=0;j<n;j++) down*=6; g=gcd(up,down); printf("Case %d: %lld/%lld\n",cas,up/g,down/g); } return 0; }
AC代码2:
#include<cstdio> #include<iostream> #include<cstring> using namespace std; __int64 dp[25][155]; __int64 gcd(__int64 x,__int64 y) { return y?gcd(y,x%y):x; } int main() { __int64 up,down,g; int T,n,x; for (int i = 1; i <= 24; i ++) for (int j = 1; j <= 150; j ++) { if (i == 1 && j <= 6) dp[i][j] = 1; for (int k = 1; k <= 6; k ++) { if (j >= k) dp[i][j] += dp[i - 1][j - k]; } } scanf("%d",&T); for(int cas=1;cas<=T;cas++) { scanf("%d%d",&n,&x); up=0,down=0; for(int i=n;i<=n*6;i++) { down+=dp[n][i]; if(x<=i) up+=dp[n][i]; } if(up==down) printf("Case %d: 1\n",cas); else if(up==0) printf("Case %d: 0\n",cas); else { g=gcd(up,down); printf("Case %d: %lld/%lld\n",cas,up/g,down/g); } } return 0; }