[洛谷]P1866 编号 (#数学 -1.10)(#搜索 -1.23)

题目描述

太郎有N只兔子,现在为了方便识别它们,太郎要给他们编号。兔子们向太郎表达了它们对号码的喜好,每个兔子i想要一个整数,介于1和Maxnumber[i]之间(包括1和Maxnumber[i])。当然,每个兔子的编号是不同的。现在太郎想知道一共有多少种编号的方法。

你只用输出答案mod 1000000007即可。如果这是不可能的,就输出0.

输入输出格式

输入格式:

第一行是一个整数N。(1≤N≤50)

第二行N个整数Maxnumber[i]。(1≤Maxnumber[i]≤1000)

输出格式:

一个整数

输入输出样例

输入样例#1

2
5 8

输出样例#1

35

思路

设n=3,3个数分别为6,12,8。

则先升向排序6,8,12。

第一个号码有6种选择

第二个号码有8-1=7(种)选择(去掉1种)

第三个号码有12-2=10(种)选择(去掉2种)

结果为6*7*10=420。由于结果可能很大,mod 1000000007。

#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	long long int n,a[51]={},i,j,s(1);//开大点 
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	sort(a+1,a+n+1);
	for(i=1;i<=n;i++)
	{
		s=s*(a[i]-i+1);
		s=s%1000000007;
	}
	cout<<s<<endl;
	return 0;
}

还有一种dfs的写法,类似于上面的数学推论,但是我写的只有30分,仅供借鉴。

#include <stdio.h>
#include <iostream>
int n,s,a[61],b[61];
using namespace std;
void dfs(int i)//当前是第i层 
{
	register int j;
	if(i==n+1)//类似于全排列的写法 
	{
		s++;
		s=s%1000000007;
		return;
	}
	for(j=1;j<=a[i];j++)//搜索算符 
	{
		if(b[j]==0)//如果没搜索过 
		{
			b[j]=1;//标记搜索过了 
			dfs(i+1);//搜索下一层 
			b[j]=0;//取消标记 
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int i;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>a[i];
	} 
	dfs(1);
	cout<<s<<endl;
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值