zoukankan      html  css  js  c++  java
  • HDOJ 1078

    标准的DAG上的DP,其实之前一直不大想得明白为什么dp[i][j]为什么一定是在(i,j)状态上的局部最优解了呢?

    其实仔细想想和我一般所做的DP是一个道理,因为运用dfs的方法,因此可以确定的是,得到了dp[i][j]的值并且已经退出了(i,j)这个状态,就可以认为已经将(i,j)所有的后继的状态的最优解已经计算出了。而记忆化搜索就是可以看作剪枝的手段。其实这么一想貌似还没什么问题了。

    个人经验:对于递归的思考千万别想深了,而是应当运用类似于数学归纳法的东西,这么一想至少我目前所遇到的问题都可以迎刃而解了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int SIZE=105;
    int map[SIZE][SIZE];
    int dp[SIZE][SIZE];
    int n,k;
    int dfs(int x,int y)
    {
    int& ans=dp[y][x];
    if(ans) return ans;
    ans=map[y][x];
    for(int i=1;i<=k;i++)
    {
    if(map[y][x-i]>map[y][x]&&x-i>=1) ans=max(ans,dfs(x-i,y)+map[y][x]);
    if(map[y-i][x]>map[y][x]&&y-i>=1) ans=max(ans,dfs(x,y-i)+map[y][x]);
    if(map[y][x+i]>map[y][x]&&x+i<=n) ans=max(ans,dfs(x+i,y)+map[y][x]);
    if(map[y+i][x]>map[y][x]&&y+i<=n) ans=max(ans,dfs(x,y+i)+map[y][x]);
    }
    return ans;
    }
    int main()
    {
    //freopen("data.in","r",stdin);
    int i,j;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
    if(n==-1&&k==-1) break;
    memset(dp,0,sizeof(dp));
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    scanf("%d",&map[i][j]);
    dfs(1,1);
    printf("%d ",dp[1][1]);
    }
    return 0;
    }

  • 相关阅读:
    Document
    Echarts 图例交互事件,及使用
    Echarts 入门之基础使用(部份 API)
    对比 continue、break 在循环中的作用
    Markdown 简要语法速成
    CSS 实现必填项前/后添加红色*、√、X、▲
    9.React Context 上下文
    [leetcode sort]179. Largest Number
    [leetcode tree]102. Binary Tree Level Order Traversal
    [leetcode tree]101. Symmetric Tree
  • 原文地址:https://www.cnblogs.com/acalvin/p/3579153.html
Copyright © 2011-2022 走看看