此题算法动态规划
令dp[i][j]表示将前i个球放入j个盒子中,显然dp[i][1]=1
若j不等于1,dp[i][j]可以转化为:将前i-1个球放入j个盒子里,再把第i个球任意放入一个盒子里的数量,加上将前i-1个球放入j-1个盒子里,再把第i个球放入剩下的那个盒子里的数量
于是dp[i][j]=dp[i-1][j-1]+j*dp[i-1][j]
于是可写出代码:
#include <iostream>
using namespace std;
const int N=105;
int dp[N][N];
int n,m;
int main()
{
for(int i=1;i<=100;i++)
{
for(int j=1;j<=100;j++)
{
if(j==1) dp[i][j]=1;
else dp[i][j]=dp[i-1][j-1]+dp[i-1][j]*j;
}
}
while(cin>>n>>m) cout<<dp[n][m]<<"\n";
return 0;
}
交上去,我们就开心地得到了20分
为什么呢?
我们发现dp[i][j]那里有一个dp[i-1][j]乘j,证明dp[i][j]的数量是阶乘级增长的,不溢出才怪
于是,我们也许会尝试用__int128骗点分:
#include <iostream>
using namespace std;
const int N=105;
__int128 dp[N][N];
int n,m;
void write(__int128 x)//__int128没有自己的输入输出,所以我们要自己写
{
int ans[1005]={0},top=0;
do
{
ans[top++]=x%10;
x/=10;
}while(x);
while(top)
{
putchar(ans[--top]+'0');
}
}
int main()
{
for(int i=1;i<=100;i++)
{
for(int j=1;j<=100;j++)
{
if(j==1) dp[i][j]=1;
else dp[i][j]=dp[i-1][j-1]+dp[i-1][j]*j;
}
}
while(cin>>n>>m)
{
write(dp[n][m]);
cout<<"\n";
}
return 0;
}
50分,看来,我们还是得用烦人的高精度,具体实现见代码注释
#include <iostream>
using namespace std;
const int N=105;
int n,m;
struct Node
{
int num[1000];//存数
int len;//存长度,方便便利
}dp[N][N];
void write(Node x)
{
for(int i=x.len;i>=1;i--) cout<<x.num[i];//由于数是倒着存的,所以要倒着输出
}
Node Add(Node A,Node B)
{
Node ans={0};//存计算出来的结果
int len=max(A.len,B.len);
for(int i=1;i<=len;i++)
{
ans.num[i]+=A.num[i]+B.num[i];//相加
if(ans.num[i]>=10)
{
//逢十进一
ans.num[i+1]++;
ans.num[i]%=10;
if(i==len) len++;
}
}
//记录长度
ans.len=len;
return ans;
}
Node Mul(Node A,int B)
{
int len=A.len;
Node ans={0};//记录计算出来的结果
for(int i=1;i<=len;i++)
{
ans.num[i]+=A.num[i]*B;//相乘
//进位
ans.num[i+1]+=ans.num[i]/10;
ans.num[i]%=10;
}
//如果还需继续进位,则继续进位
while(ans.num[len+1]>0)
{
len++;
ans.num[len+1]=ans.num[len]/10;
ans.num[len]%=10;
}
ans.len=len;//记录长度
return ans;
}
int main()
{
//动态规划部分
for(int i=1;i<=100;i++)
{
for(int j=1;j<=100;j++)
{
if(j==1)
{
dp[i][j].len=1;
dp[i][j].num[1]=1;
}
else dp[i][j]=Add(dp[i-1][j-1],Mul(dp[i-1][j],j));
}
}
//输出部分
while(cin>>n>>m)
{
if(n<m) cout<<0;//n<m需特判
write(dp[n][m]);
cout<<"\n";
}
return 0;
}