抽屉上锁(计数dp+高精度)

3 篇文章 0 订阅

题目描述
现在我们来考虑对一个有N层抽屉的柜子上锁。该柜子中的所有抽屉都整齐地排布在一列上,并且相邻上下两个抽屉之间没有木板分隔。也就是说,如果第一层的抽屉没有锁上,即使第二层的抽屉锁上了,我们也能够拿到第二层抽屉里面的东西(将第一层的抽屉抽出来)。我们的问题是,如果要求恰好只有M层抽屉里面的东西拿不到,总共有多少种不同的锁抽屉方式呢?
输入
输入包括两个数N和M,意义如题目中所描述。
输出
输出仅包含一个整数,即答案。
样例输入
6 4
样例输出
6
提示
对于20%的数据,有1≤N, M≤10;
对于50%的数据,有1≤N, M≤65;
对于100%的数据,有1≤N, M≤300。
解题思路:每个抽屉有锁和不锁两种状态,而且这层抽屉能否拿出只与自己和上一层抽屉的状态有关,所以想到dp。
dp[i][j][0]表示i层抽屉有j个拿不到并且这层抽屉是没锁的,dp[i][j][1]表示表示i层抽屉有j个拿不到并且这层抽屉是上锁的。
状态转移方程位(根据方程自己看一下很容易就理解了):
dp[i][j][1]=dp[i-1][j-1][1],dp[i-1][j][0];
dp[i][j][0]=dp[i-1][j][0],dp[i-1][j][1];
注意:在计数过程中,因数太大会导致爆炸,所以采用高精度

#include<bits/stdc++.h>
//#pragma GCC optimize(2)
#define N 100005
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
const int mod=1e9+7;
const int INF=0x7fffffff;
const int inf=0x3f3f3f3f;
const ull base=131;
//高精加
string jia(string a,string b){
    string s="";
    int aa[1100],bb[1100],cc[1100];
    memset(aa,0,sizeof(aa));
    memset(bb,0,sizeof(bb));
    memset(cc,0,sizeof(cc));
    int lena=a.size(),lenb=b.size();
    for(int i=1;i<=lena;i++) aa[i]=a[lena-i]-'0';
    for(int i=1;i<=lenb;i++) bb[i]=b[lenb-i]-'0';
    int len=1;
    while(len<=lena||len<=lenb){
        cc[len]+=aa[len]+bb[len];
        if(cc[len]>=10){
            cc[len+1]=cc[len]/10;
            cc[len]%=10;
        }
        len++;
    }
    while(!cc[len]&&len>1) len--;
    for(int i=len;i>=1;i--) s+=cc[i]+'0';
    return s;
}

string dp[310][310][2];
int n,m;
int main(){
    cin>>n>>m;
    dp[0][0][1]=dp[1][0][0]=dp[1][1][1]="1";
    for(int i=2;i<=n;i++) dp[i][0][0]=jia(dp[i-1][0][0],dp[i-1][0][1]),dp[i][0][1]=dp[i-1][0][0];//初始化边界
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m&&i>=j;j++){
            dp[i][j][1]=jia(dp[i-1][j-1][1],dp[i-1][j][0]);
            dp[i][j][0]=jia(dp[i-1][j][0],dp[i-1][j][1]);
        }
    }
    cout<<jia(dp[n][m][0],dp[n][m][1]);
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值