洛谷 P1655 小朋友的球 题解
思路
\(dp\),dp[i][j] 为将 i 个球放入 j 个盒子的方案数。
每一步放球时,可以放在一个新的盒子里(1种情况),或放在已占的盒子里(j种情况)
所以:当只有一个盒子时 (j=1),dp[i][j] = 1
否则 dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j] * j
代码:
#include<bits/stdc++.h>
using namespace std;
int dp[105][105];
int main()
{
int n, m;
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] << endl;
}
return 0;
}
20 分
正解:
看测试点,有些点输出的是负数(Wrong Answer. wrong answer On line 1 column 1, read -, expected 2.)
一定是溢出了,试试 long long (20 分) 甚至 __int128 (50 分)
正解是高精度。
代码
#include<bits/stdc++.h>
using namespace std;
struct node
{
int num[1005];
int len;
};
node dp[105][105];
void w(node x)//输出
{
for(int i = x.len; i >= 1; i --)
{
putchar(x.num[i] + '0');
}
}
node operator + (node A, node B)//高精加法
{
node c = {0};
int l = max(A.len, B.len);
for(int i = 1; i <= l; i ++)
{
c.num[i] += A.num[i] + B.num[i];
if(c.num[i] >= 10)
{
c.num[i + 1] ++;
c.num[i] %= 10;
if(i == l) l ++;
}
}
c.len = l;
return c;
}
node operator * (node A, int B)//高精乘法
{
int l = A.len;
node c = {0};
for(int i = 1; i <= l; i ++)
{
c.num[i] += A.num[i] * B;
c.num[i + 1] += c.num[i] / 10;
c.num[i] %= 10;
}
while(c.num[l + 1] > 0)
{
l ++;
c.num[l + 1] = c.num[l] / 10;
c.num[l] %= 10;
}
c.len = l;
return c;
}
int main()
{
int n, m;
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] = dp[i - 1][j - 1] + dp[i - 1][j] * j;
}
}
while(cin >> n >> m)
{
if(n < m)//记着特判,如果 n < m,那么肯定无法满足要求
{
cout << 0 << endl;
continue;
}
w(dp[n][m]);
cout << endl;
}
return 0;
}
hello, I'm yuzihang, if you need to copy this, please quote this url: https://www.cnblogs.com/yuzihang/articles/17438626.html

浙公网安备 33010602011771号