原题链接:化学品问题
解题思路:
用dp[i][0]记录第i个位置不放那个药品的方案数
dp[i][1]记录第i个位置放药品的方案数
参考代码:
#include<bits/stdc++.h> using namespace std; const int N = 35; typedef long long ll; ll t,m,n,sum = 0; int dp[N][5];//dp[i][0]表示第i位不放药品的方案数,dp[i][1]表示第i位放药品的方案数 void solve(){ sum = 0; memset(dp,0,sizeof(dp)); dp[0][0] = 1;//初始化dp[0][0]为1 当i==m时需要要用到这个情况 先看到后面再回来看 //(表示后面连续的m个位置都放药品的方案数为1) dp[1][1] = 1;dp[1][0]=1;//初始化第一位无论放不放那个药都是一种方案 //遍历完善dp数组 for(int i = 2;i<=n;i++){ dp[i][0] = dp[i-1][0] + dp[i-1][1];//第i位不放药品的方案数(前面一个放不放都可以)等于前一位 //放药品的方案数加上不放药品的方案数 if(i<m) dp[i][1] = dp[i-1][0] + dp[i-1][1];//i小于m时放药品还不用考虑爆炸 else{//i>=m 放药品时要考虑爆炸的可能 sum+=dp[i-1][0];//首先加上前一个不放药品(前面一个不妨就不会构成连续的m个)的方案数 sum+=dp[i-1][1] - dp[i-m][0] ;//前面一个放了药品,就必须避免这m个都放药品 //的情况, 他的情况总数应该是这相邻m个的 前一个位置不放药品的方案数 //例如:1 2 3 4 5;当i = 5,m = 3时,要去掉3 4 5都放药品的方案数; //那就是2号位不放药品的方案数 原因--->确定3 4 5位置为1(放了药品); //_ _ 1 1 1 显然 2号为不能再为1,这样的方案数就是2号位为0的方案数 //(如果算上了2号位放药品的方案数那么会导致2 3 4成了连续的m个药品) //当i==m的时候 减去这m个都是1(放药品)的方案 应该是1 即1到i都是放药品这一种方案 //所以先设置dp[0][0] = 1; dp[i][1] = sum;//sum就是第i个放药品的数目 sum = 0;//记得清0 } } } int main(){ cin>>t; while(t--){ cin>>n>>m; solve(); cout<<dp[n][0] + dp[n][1] <<endl; } return 0; }
0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复