码迷,mamicode.com
首页 > 其他好文 > 详细

蓝桥杯竞赛题《地宫取宝》DP做法

时间:2015-04-11 01:13:19      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:

问题描述
  X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。   地宫的入口在左上角,出口在右下角。   小明被带到地宫的入口,国王要求他只能向右或向下行走。   走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。   当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。   请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。
输入格式
  输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12)   接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值
输出格式
  要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。
样例输入
2 2 2  1 2  2 1
样例输出
2
样例输入
2 3 2  1 2 3  2 1 5
样例输出
14
就下来是代码,网上的大都是dfs做法,但是此题DP也可解,用思维DP维护,不太会描述,看代码吧!dp[i][j][p][k]表示i,j点价值为p方法数为k时的方案数。
 1 #include<stdio.h>
 2 #include<string.h>
 3 #define mod 1000000007
 4 int dp[55][55][15][15];
 5 int a[55][55];
 6 int main()
 7 {
 8     int n,m,K;
 9     while(~scanf("%d%d%d",&n,&m,&K))
10     {
11         for(int i=1;i<=n;i++)
12             for(int j=1;j<=m;j++)
13             {
14                 scanf("%d",&a[i][j]);
15                 a[i][j]++;//加1是为了第一步不拿时好操作,如果第一步不拿则置为0,以便后面更新
16             }
17         memset(dp,0,sizeof(dp));
18         dp[1][1][a[1][1]][1]=dp[1][1][0][0]=1;//第一步拿和不拿置为1
19         for(int i=1;i<=n;i++)
20         {
21             for(int j=1;j<=m;j++)
22             {
23                 if(i==1&&j==1) continue;
24                 int x=a[i][j];
25                 for(int p=a[i][j];p<=13;p++)//暴力搜之前的点中大于等于a[i][j]的情况,此时该点不拿
26                 {
27                     for(int k=0;k<=K;k++)
28                     {
29                         if(i-1>0) dp[i][j][p][k]=(dp[i][j][p][k]+dp[i-1][j][p][k])%mod;
30                         if(j-1>0) dp[i][j][p][k]=(dp[i][j][p][k]+dp[i][j-1][p][k])%mod;
31                     }
32                 }
33                 for(int p=0;p<a[i][j];p++)//之前的点小于此时的点的值,此时有拿和不不拿两种
34                 {
35                     for(int k=0;k<=K;k++)
36                     {
37                         if(i-1>0)
38                         {
39                             dp[i][j][p][k]=(dp[i][j][p][k]+dp[i-1][j][p][k])%mod;//不拿
40                             dp[i][j][x][k+1]=(dp[i][j][x][k+1]+dp[i-1][j][p][k])%mod;//此时为拿
41                         }
42                         if(j-1>0)
43                         {
44                             dp[i][j][p][k]=(dp[i][j][p][k]+dp[i][j-1][p][k])%mod;//不拿
45                             dp[i][j][x][k+1]=(dp[i][j][x][k+1]+dp[i][j-1][p][k])%mod;//此时拿
46                         }
47                     }
48                 }
49             }
50         }
51         int ans=0;
52         for(int i=1;i<=13;i++)
53             ans=(ans+dp[n][m][i][K])%mod;
54         printf("%d\n",ans);
55     }
56     return 0;
57 }

 

蓝桥杯竞赛题《地宫取宝》DP做法

标签:

原文地址:http://www.cnblogs.com/TangCan/p/4415972.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!