BZOJ4563[Haoi2016]放棋子

 

题目描述  Description
给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在
这个矩阵上放N枚棋子(障碍的位置不能放棋子),要求你放N个棋子也满足每行只有一枚棋子,每列只有一枚棋的限制,求有多少种方案。
输入描述  Input Description

第一行一个N,接下来一个N*N的矩阵。N<=200,0表示没有障碍,1表示有障碍,输入格式参考样例

输出描述  Output Description
一个整数,即合法的方案数。
样例输入 Sample Input
2
0 1
1 0
样例输出 Sample Output
1
数据范围及提示 Data Size & Hint
 

仔细读完题发现输入的那个矩阵一点用也没有,因为可以通过平移变成障碍全在对角线上的图。继续来思考这个问题,问题转化为将1~n这N个数排列,要求第i个数不能排列在第i个位置上,这被称之为错排问题。考虑怎么递推。设f(i)表示i个数的错拍方案数,我们要将第i个数插入之前i-1个数,(因为第i个数不能插在i位置上),假如i将插在j位置上,j有两种选择,一种是j填到i的位置上,于是问题就转化为了f(i-2);另一种j填到另外i-2的位置中,我们设新填的位置为k(k!=i && k!=j),现在我们就需要把k这个数再放在i-1个数中了,即f(i-1),由于j有i-1种情况,所以我们最后再乘一个(i-1),所以递推公式就变成了f(i)=(f(i-1)+f(i-2))*(i-1),推到这一步,我们再写一个高精度支持高加高,高乘低即可。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
#define mem(a,b) memset(a,b,sizeof(a))
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
const int maxn=1010;
struct data
{
    int l,v[maxn];
    data(){l=1;mem(v,0);}
    data operator = (const int& s)
    {
        v[1]=s;
        while(v[l]>9)v[l+1]=v[l]/10,v[l]%=10,l++;
        return *this;
    }
    data operator = (const data& s)
    {
        l=s.l;
        for(int i=1;i<=l;i++)v[i]=s.v[i];
        return *this;
    }
    data operator + (const data& s)const
    {
        data c;c.l=max(l,s.l)+1;
        for(int i=1;i<=c.l;i++)c.v[i]=v[i]+s.v[i];
        for(int i=1;i<c.l;i++)if(c.v[i]>9)c.v[i+1]+=c.v[i]/10,c.v[i]%=10;
        while(c.v[c.l]>9)c.v[c.l+1]=c.v[c.l]/10,c.v[c.l]%=10,c.l++;
        while(!c.v[c.l])c.l--;
        return c;
    }
    data operator * (const int& s)const
    {
         data c;c.l=l;
         for(int i=1;i<=c.l;i++)c.v[i]=v[i]*s;
         for(int i=1;i<c.l;i++)if(c.v[i]>9)c.v[i+1]+=c.v[i]/10,c.v[i]%=10;
         while(c.v[c.l]>9)c.v[c.l+1]=c.v[c.l]/10,c.v[c.l]%=10,c.l++;
         while(!c.v[c.l])c.l--;
         return c;
    }
}f[210];
void print(data a){for(int i=a.l;i;i--)printf("%d",a.v[i]);}
int n;
int main()
{
    n=read();
    f[1]=0;f[2]=1;
    for(int i=3;i<=n;i++)f[i]=(f[i-1]+f[i-2])*(i-1);
    print(f[n]);
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/FYH-SSGSS/p/6918461.html

本项目是一个基于SSM(Spring+SpringMVC+MyBatis)框架和Vue.js前端技术的大学生第二课堂系统,旨在为大学生提供一个便捷、高效的学习和实践平台。项目包含了完整的数据库设计、后端Java代码实现以及前端Vue.js页面展示,适合计算机相关专业的毕设学生和需要进行项目实战练习的Java学习者。 在功能方面,系统主要实现了以下几个模块:用户管理、课程管理、活动管理、成绩管理和通知公告。用户管理模块支持学生和教师的注册、登录及权限管理;课程管理模块允许教师上传课程资料、设置课程时间,并由学生进行选课;活动管理模块提供了活动发布、报名和签到功能,鼓励学生参与课外实践活动;成绩管理模块则用于记录和查询学生的课程成绩和活动参与情况;通知公告模块则实时发布学校或班级的最新通知和公告。 技术实现上,后端采用SSM框架进行开发,Spring负责业务逻辑层,SpringMVC处理Web请求,MyBatis进行数据库操作,确保了系统的稳定性和扩展性。前端则使用Vue.js框架,结合Axios进行数据请求,实现了前后端分离,提升了用户体验和开发效率。 该项目不仅提供了完整的源代码和相关文档,还包括了详细的数据库设计文档和项目部署指南,为学习和实践提供了便利。对于基础较好的学习者,可以根据自己的需求在此基础上进行功能扩展和优化,进一步提升自己的技术水平和项目实战能力。
本项目是一个基于SSM(Spring+SpringMVC+MyBatis)后端框架与Vue.js前端框架的个人健康信息管理系统。该项目旨在为个人提供一个便捷、高效的健康信息管理平台,通过该系统,用户可以轻松地记录、查询和分析自己的健康数据。 在技术选型上,后端采用了Spring框架进行依赖注入和事务管理,SpringMVC负责处理Web请求,MyBatis则用于数据库操作,实现了前后端的分离。前端则使用了Vue.js框架,结合Vue Router进行页面路由管理,以及Vuex进行状态管理,确保了用户界面的响应性和交互性。 系统的主要功能包括用户注册与登录、健康数据录入(如身高、体重、血压等)、健康数据查询与分析、健康建议推送等。用户可以通过系统直观地查看自己的健康趋势,并根据系统提供的建议调整生活习惯。 数据库设计方面,系统采用了关系型数据库MySQL,设计了用户表、健康数据表等,确保了数据的完整性和安全性。此外,项目还包含了详细的文档和论文资料,为使用者提供了完整的开发背景和技术实现细节。 对于计算机相关专业的毕设学生而言,该项目不仅提供了一个实际的应用场景,还涵盖了从需求分析到系统实现的完整开发流程,是一个理想的实践平台。对于Java学习者,该项目也是一个很好的实战练习,可以在理解现有代码的基础上,进一步探索和实现更多功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值