L3-3 收集宝物 (30 分)

出题人:DS课程组
单位:临沂大学
小明有一张藏宝图,上面有n*m个房间,每个房间里面都有一个有一定价值的宝物,小明只能从左上角的房间进入,且每次只能向右或向下行走,最终只能从最右下的房间出来。经过某个房间时,如果该房间中的宝物价值比小明手中任何宝物价值都大,小明就可以拿走它,当然,也可以不拿。当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝物就可以送给小明。请你帮小明算一算,他有多少种不同的行动方案能获得这k件宝贝。

输入格式

输入第一行3个整数n,m,k(1<=n,m<=50,1<=k<=12),其间空格分割。

接下来有n行数据,每行有m个整数Vi(0<=Vi<=12),代表这个房间里的宝物的价值。

输出格式

要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对1000000007取模的结果。

输入样例

2 2 2
1 2
2 1

输出样例

2

输入样例2

2 3 2
1 2 3
2 1 5

输出样例2

14

思路

dfs,注意题目数据,需要取模,因此普通的dfs肯定会超时,需要用到记忆化搜索,具体看代码

#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;

int val[51][51];
int n, m, k;
int dp[51][51][13][13];
int dfs(int x, int y, int ma, int sum)
{
	if(x > n || y > m || sum > k)
		return 0;
	if(dp[x][y][ma][sum] != -1)
		return dp[x][y][ma][sum];
	int temp = val[x][y];
	int res = 0;
	if(x == n && y == m){
		if(sum == k || (sum == k-1 && temp > ma))
			return 1;
		else
			return 0;
	}
	if(temp > ma){
		res += dfs(x, y+1, temp, sum+1);
		res %= mod;
		res += dfs(x+1, y, temp, sum+1);
		res %= mod;
	}
	res += dfs(x, y+1, ma, sum);
	res %= mod;
	res += dfs(x+1, y, ma, sum);
	dp[x][y][ma][sum] = res%mod;
	return res%mod;
}
int main()
{
	cin>>n>>m>>k;
	memset(dp, -1, sizeof(dp));
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			cin>>val[i][j];
	cout<<dfs(1, 1, -1, 0)<<endl;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值