您的位置:首页 > 编程语言 > C语言/C++

CodeVS 1039 数的划分

2016-05-25 22:05 260 查看

题目=v=

CodeVS 1039 数的划分

题解QAQ

很明显这是一道动规嘛

【哪里明显了!!!

因为标签上写着

【摔!

因为天梯它在动规里

【滚!

不闹了QAQ

其实一开始我天真地以为可以用插板法QAQ

可是题目要求顺序不考虑残忍地打破了我美好的幻想

所以。。。

让我们试一试动规? //这逻辑好牵强QAQ

用f[i][j]表示i分成k份的方案总数

然后。。。

我们惊喜地发现

我们经过百度发现

总之。。。

将i分成k份分为两种情况考虑

1. 分成的k份中存在某一份为1

2. 分成的k份均不为1

对于情况一

方案数=不考虑这一份1的方案数=f[i-1][j-1]

对于情况二

等价于每一份各删去1

方案数=f[i-j][j]

因此f[i][j]=f[i-1][j-1]+f[i-j][j]

然后。。。

看起来似乎不能优化成一维数组?

我也这么觉得233

现在的空间复杂度应是O(k*n)吧

200*6很明显不会超嘛QVQ

那还优化什么呀

所以就直接上代码啦=v=

代码

C++

#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
int n,k;
scanf("%d%d",&n,&k);
int f[201][7];
for (int i=1;i<=n;i++)
{
f[i][1]=1;
for (int j=2;j<=min(i,k);j++)
{
if (j==i)
f[i][j]=1;
else
f[i][j]=f[i-1][j-1]+f[i-j][j];
}
}
printf("%d",f
[k]);
}


Pascal

//说实话这是C++翻译来的233

uses math;
var
n,k,i,j:integer;
f:array[1..200,1..6] of longint;
begin
readln(n,k);
for i:=1 to n do
begin
f[i,1]:=1;
for j:=2 to min(i,k) do
begin
if j=i
then f[i,j]:=1
else f[i,j]:=f[i-1,j-1]+f[i-j,j];
end;
end;
writeln(f[n,k]);
end.


最后再给Pascal一点建议:

放心大胆地用longint!!!

不要再一天到晚用integer!!!

以前我一直是估算一下integer肯定不能过才写longint

然后次次都是WA了RE了再改个类型重新提交

但是C++里面随手写的都是int

int和longint范围是一样的

和integer范围一样的C++叫short int!!!

基本上随手都是int除非dp真的空间复杂度有点高了才用short int

【其实唠叨了半天可能本来就只有我每天都是integer?!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Codevs C++ Pascal