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

链接:https://ac.nowcoder.com/acm/contest/24213/1014
来源:牛客网
 
 
题目描述
小A最近开始沉迷买彩票,并且希望能够通过买彩票发家致富。已知购买一张彩票需要3元,而彩票中奖的金额分别为1,2,3,4元,并且比较独特的是这个彩票中奖的各种金额都是等可能的。现在小A连续购买了n张彩票,他希望你能够告诉他至少能够不亏本的概率是多少。
输入描述:
一行一个整数N,为小A购买的彩票数量一行一个整数N,为小A购买的彩票数量一行一个整数N,为小A购买的彩票数量
输出描述:
输出一个最简分数a/b,表示小A不亏本的概率。若概率为1,则输出1/1,概率为0,则输出0/1。输出一个最简分数a/b,表示小A不亏本的概率。 \\若概率为1,则输出1/1,概率为0,则输出0/1。输出一个最简分数a/b,表示小A不亏本的概率。若概率为1,则输出1/1,概率为0,则输出0/1。
示例1
输入
复制
2
2
输出
复制
3/8
3/8
备注:
0≤n≤300 \leq n \leq 300≤n≤30

分析

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:41  er007  阅读(74)  评论(0编辑  收藏  举报