您的位置:首页 > 大数据 > 人工智能

Timus Online Judge 1017 Staircases(记忆化搜索)

2015-10-26 12:27 483 查看
这道题目在Timus上面的难度系数是165,可是当你做了之后就会发现,这道题目的难度系数大概也就七八十的样子,大概动态规划一类的问题都是这样吧,推导出了状态转移方程就没什么好说的,然而我并没有推导出状态转移方程,只是用了个记忆化搜索。

题目大意:用N个格子搭楼梯,每个阶梯之间严格递增,不允许相等的情况,至少要有两个阶梯,每个阶梯至少用一个格子,并没有对相邻阶梯的高度进行限制。问,有多少种搭建方法?

如果你是新手,或许很难去找到相应的问题模型来对这道题目进行套用,因为你可能真的像题目的描述那样,一步一步的去搭建。

但如果你以前就学过dp,并且也知道有数的划分这类型的问题,那么,稍加思考,这道题目就感觉so easy!

谈到数的划分,那就直接明了了吧,我相信,我们需要考虑的就是把一个数N划分为K(k  > 1)个不相同的数,每个数要大于0,这样思路转换一下,就可以了。

枚举一下所有的可能,然后加上记忆化搜索,就完事儿了。下面还是照例献上自己丑陋的代码。

#include <iostream>
#include <cstring>
#define ll long long
using namespace std;
ll dp[501][501];
ll solve(int sum, int mx) {//由未知的k个不同的小于mx数来组成sum,事实上,我们并不需要知道k是多少
if (sum == 0) return 1;
if (dp[sum][mx] != -1) return dp[sum][mx];
ll ans = 0;
for (int i = min(mx - 1, sum); i >= 1; --i) {//sum - i 出现负数的情况
ans += solve(sum - i, i);
}
return dp[sum][mx] = ans;
}
int main() {
ll N;
cin >> N;
memset(dp, -1, sizeof dp);
ll ans = 0;
for (int i = N - 1; i >= 1; --i) {//i不能从N开始枚举,为了避免只有一个台阶的情况
ans += solve(N - i, i);
}
cout << ans << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: