zoukankan      html  css  js  c++  java
  • 问题 1436: 地宫取宝 (dp)

    题目传送门

    时间限制: 1Sec 内存限制: 128MB 提交: 423 解决: 94

    题目描述
    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  3  2 
    1  2  3 
    2  1  5 
    样例输出
    14

    思路
    dfs记忆化搜索,这题要考虑的参数:宝物的大小和个数
    所以我们要四个参数;另外由于宝物的大小可能为0,所以要初始为
    -1,则dp里面要+1;
    或者用dp;dp[i][j][k][c]为走到(i,j)的时候,手上共K个物品,最大价值小于c
    具体看代码。

    代码:
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod=1e9+7;
    int n,m,kk;
    ll dp[55][55][13][13];
    int a[55][55];
    
    ll dfs(int x,int y,int num,int c)
    {
        if(dp[x][y][num][c+1]!=-1) return dp[x][y][num][c+1];
        if(x==n&&y==m) {
            if(num==kk) return 1;
            if(num==kk-1&&a[x][y]>c) return 1;
        }
       ll ans=0;
       if(x<n)
       {
           if(a[x][y]>c) ans+=(dfs(x+1,y,num+1,a[x][y]))%mod;
           ans%=mod;
           ans+=(dfs(x+1,y,num,c))%mod;
           ans%=mod;
       }
       if(y<m)
       {
           if(a[x][y]>c) ans+=(dfs(x,y+1,num+1,a[x][y]))%mod;
            ans%=mod;
           ans+=(dfs(x,y+1,num,c))%mod;
           ans%=mod;
       }
    
        return dp[x][y][num][c+1]=ans;
    }
    int main()
    {
       while(~scanf("%d %d %d",&n,&m,&kk))
       {
           memset(dp,-1,sizeof(dp));
           for(int i=1;i<=n;i++)
           {
               for(int j=1;j<=m;j++)
               {
                   scanf("%d",&a[i][j]);
               }
           }
         printf("%lld
    ",dfs(1,1,0,-1));//注意这里要初始为-1
       }
        return 0;
    }
    dfs记忆化搜索
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define mod 1000000007
    #define N 55
    int n,m,kk;
    int a[N][N];
    ll dp[N][N][13][13];
    
    int main()
    {
       while(~scanf("%d %d %d",&n,&m,&kk))
       {
           memset(a,0,sizeof(a));
           for(int i=1;i<=n;i++)
           {
               for(int j=1;j<=m;j++)
                scanf("%d",&a[i][j]);
           }
           for(int i=1;i<=n;i++)
           {
               for(int j=1;j<=m;j++)
               {
                   for(int k=0;k<=kk;k++)
                   {
                       for(int c=0;c<13;c++)
                       {
                           ll na=0,buna=0;
                            if(i==1&&j==1){
                if(!k||(k==1&&c>a[i][j]))dp[i][j][k][c]=1;
                continue;
            }
            if(k&&c>a[i][j])na=dp[i-1][j][k-1][a[i][j]]+dp[i][j-1][k-1][a[i][j]];
            buna=dp[i-1][j][k][c]+dp[i][j-1][k][c];
            dp[i][j][k][c]=na+buna;
            dp[i][j][k][c]%=mod;
                       }
                   }
               }
           }
           printf("%lld
    ",dp[n][m][kk][12]);
       }
        return 0;
    }
    dp
     


  • 相关阅读:
    python调包——hashlib加密
    初识-图论基础+拓扑排序的实现
    初识 基本数据结构和stl
    【寒假作业三】-带着作业的幌子打开影视剧的奇妙体验和学会挂作业的机
    scapy模块的学习
    【寒假作业三】——高级代码拼接工人的养成(改)
    寒假作业二-自救指南(网络基础)
    【寒假作业一】-编写踩雷指南
    寒假作业一-Github部分
    markdown基础(试水)
  • 原文地址:https://www.cnblogs.com/zhgyki/p/10356631.html
Copyright © 2011-2022 走看看