1014 小A买彩票 认真地题解 线性DP 动态规划

链接:https://ac.nowcoder.com/acm/contest/24213/1014
来源:牛客网

题目描述

小A最近开始沉迷买彩票,并且希望能够通过买彩票发家致富。已知购买一张彩票需要3元,而彩票中奖的金额分别为1,2,3,4元,并且比较独特的是这个彩票中奖的各种金额都是等可能的。现在小A连续购买了n张彩票,他希望你能够告诉他至少能够不亏本的概率是多少。

输入描述:

一行一个整数N,为小A购买的彩票数量一行一个整数N,为小A购买的彩票数量NA

输出描述:

输出一个最简分数a/b,表示小A不亏本的概率。若概率为1,则输出1/1,概率为0,则输出0/1。输出一个最简分数a/b,表示小A不亏本的概率。 \\若概率为1,则输出1/1,概率为0,则输出0/1。a/bA11/100/1
示例1

输入

复制
2

输出

复制
3/8

备注:

0≤n≤300 \leq n \leq 300n30

分析

n = 0 的时候,肯定不会亏输出 1/1

有4个选项,n次选择。所以总共有 4 ^ n 的结果作为分母。

4 ^ 30 = 2 ^ 60 所以要开LL

n >=1 的时候,首先看n = 1 ,有2/4的概率是亏的。

随着n 的增大,最后一次的方案数总是和最后一次有关,所以第i次选择是线性DP 的一个变量

每次选择的区别还在于最后得到的金钱数,所以有j 块钱是线性DP 的一个变量

得到变量:dp[i][j] 表示第i次选择总共得到了j块钱

第i 次和第i - 1 次在金钱方面的区别就是 j -1 ,j - 2 ,j - 3 ,j - 4

所以第i 次得到j块钱的方案数 按照搜索的分部加法原理就是 dp[i][j] = dp[i-1][j-1] + dp[i-1][j-2] + dp[i-1][j-3] + dp[i-1][j-4]

初始化dp[1][1] = dp[1][2] = dp[1][3] = dp[1][4] = 1

i 从 2 开始循环

j 从 当前轮最小金额数 i 开始循环到 4 * i

最后用最大公约数除分子和分母,得到通分

 

写了这么久题解,终于开始认真写了

//-------------------------代码----------------------------

#define int LL
const int N = 2000;
int n,m;
int dp[N][N];
void solve()
{
cin>>n;
if(n == 0) {
cout<<"1/1";
rt;
}
for(int j=1;j<=4;j++)
dp[1][j]=1;

fo(i,2,n) {
fo(j,i,i*4) {
dp[i][j] = dp[i-1][j-1] + dp[i-1][j-2] + (j-3 >= 0 ?dp[i-1][j-3]:0) +
(j-4>=0?dp[i-1][j-4]:0);
}
}
LL sum = 0;
fo(i,3*n,4*n) {
sum += dp[n][i];
}
LL f = pow(4,n);
int z = gcd(f,sum);
cout<< sum / z <<'/'<< f / z;
rt;
}

signed main(){
clapping();TLE;

// int t;cin>>t;while(t -- )
solve();
// {solve(); }
return 0;
}

/*样例区


*/

//------------------------------------------------------------

posted @ 2022-07-07 04:29  er007  阅读(29)  评论(0编辑  收藏  举报