zoukankan      html  css  js  c++  java
  • C++-蓝桥杯-地宫取宝[2014真题][记忆化搜索]

    一开始想的是dp四维状态都设好了,然后写起来贼恶心

    然后改搜索,四类分支都想好了,但是复杂度又不对?

    放弃后,看题解,艹,还真是两者结合起来,记忆化搜索。

    好吧,不愧是你,蓝桥杯,这么喜欢暴力算法!

    PS:

    对于一个搜索状态,其返回值可能为0,所以数组初值要赋为-1

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 using namespace std;
     5 const int MOD=1e9+7;
     6 int n,m,k;
     7 int v[55][55];
     8 int f[55][55][15][15];
     9 int dfs(int x,int y,int num,int max){
    10     if(f[x][y][num][max+1]!=-1)return f[x][y][num][max+1];
    11     if(x==n&&y==m)return f[x][y][num][max+1]=(num==k||(num==k-1&&max<v[x][y]));
    12     int ans=0;
    13     if(x+1<=n){
    14         if(max<v[x][y])ans=(ans+dfs(x+1,y,num+1,v[x][y]))%MOD;
    15         ans=(ans+dfs(x+1,y,num,max))%MOD;
    16     }
    17     if(y+1<=m){
    18         if(max<v[x][y])ans=(ans+dfs(x,y+1,num+1,v[x][y]))%MOD;
    19         ans=(ans+dfs(x,y+1,num,max))%MOD;
    20     }
    21     return f[x][y][num][max+1]=ans;
    22 }
    23 int main() {
    24     cin>>n>>m>>k;
    25     for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>v[i][j];
    26     memset(f,-1,sizeof(f));dfs(1,1,0,-1);
    27     cout<<f[1][1][0][0]<<endl;
    28     return 0;
    29 }

     以上是普遍流传的版本,但是对于类似dp的搜索我喜欢从后往前搜索

     代码略有不同,但是似乎更快,0msAC,空间也更小!?

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 using namespace std;
     5 const int MOD=1e9+7;
     6 int n,m,k,v[55][55];
     7 int f[55][55][15][15];
     8 int dfs(int x,int y,int num,int max){
     9     if(f[x][y][num][max+1]!=-1)return f[x][y][num][max+1];
    10     if(x==1&&y==1)return f[x][y][num][max+1]=(num==0||(num==1&&v[1][1]<max));
    11     int ans=0;
    12     if(x>1){
    13         if(v[x][y]<max)ans=(ans+dfs(x-1,y,num-1,v[x][y]))%MOD;
    14         ans=(ans+dfs(x-1,y,num,max))%MOD;
    15     }
    16     if(y>1){
    17         if(v[x][y]<max)ans=(ans+dfs(x,y-1,num-1,v[x][y]))%MOD;
    18         ans=(ans+dfs(x,y-1,num,max))%MOD;
    19     }
    20     return f[x][y][num][max+1]=ans;
    21 }
    22 int main(){
    23     cin>>n>>m>>k;
    24     for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>v[i][j];
    25     memset(f,-1,sizeof(f));cout<<dfs(n,m,k,15)<<endl;
    26     return 0;
    27 }
  • 相关阅读:
    TCP/UDP常见端口参考
    HTTP状态码对照表 HTTP response codes
    HTTP请求方法对照表
    服务器返回的各种HTTP状态码介绍
    HTTP响应头和请求头信息对照表
    简析TCP的三次握手与四次分手
    什么是JDK
    jmeter使用IP欺骗压力测试
    jmeter制造安全证书
    Python 变量作用域
  • 原文地址:https://www.cnblogs.com/JasonCow/p/12424173.html
Copyright © 2011-2022 走看看