zoukankan      html  css  js  c++  java
  • NOIP2000方格取数(洛谷,动态规划递推)

    先上题目:

    P1004 方格取数

    下面上ac代码:

    ///如果先走第一个再走第二个不可控因素太多
    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll f[11][11][11][11];
    ll a[11][11];
    int main()
    {
        ios::sync_with_stdio(false);
        ll n,xx,yy,zz;
        cin>>n;
        while(scanf("%lld %lld %lld",&xx,&yy,&zz)==3&&!(xx==0&&yy==0&&zz==0))
            a[xx][yy]=zz;//导入基本数据
        //我们需要f[n][n][n][n]作为答案,它表示走完两次的总数
    //    f[1][1][1][1]=a[1][1];//这里不用赋初值
        for(ll i=1;i<=n;i++)
            for(ll j=1;j<=n;j++)
                for(ll x=1;x<=n;x++)
                    for(ll y=1;y<=n;y++)
                    {
                        f[i][j][x][y]=a[i][j]+a[x][y]+max(max(max(f[i-1][j][x-1][y],f[i-1][j][x][y-1]),f[i][j-1][x-1][y]),f[i][j-1][x][y-1]);
    //                    f[i][j][x][y]=max(f[i][j][x][y],f[i-1][j][x-1][y]+a[i][j]+a[x][y]);
    //                    f[i][j][x][y]=max(f[i][j][x][y],f[i-1][j][x][y-1]+a[i][j]+a[x][y]);
    //                    f[i][j][x][y]=max(f[i][j][x][y],f[i][j-1][x-1][y]+a[i][j]+a[x][y]);
    //                    f[i][j][x][y]=max(f[i][j][x][y],f[i][j-1][x][y-1]+a[i][j]+a[x][y]);
                        if(i==x&&j==y)
                            f[i][j][x][y]-=a[i][j];
                    }
        cout<<f[n][n][n][n]<<endl;
    }
    点击加号展开代码

    然后讲思路:

    1.如果先走第一个,第一个走完了再走第二个会有很多不可控因素(我就摔在这个坑上)

    2.这题其实可以看作两个人同时走

    每一回合有四种可能:

    @1,两个同时向右走

    @2,两个同时向下走

    @3,第一个向右走,第二个向下走

    @4,第一个向下走,第二个向右走

    所以需要四个连环的for循环

    用i,j表示第一个的坐标,x,y表示第二个的坐标

    如果他们同时相遇,就相当于把一个格子的数字拿了两次,再减掉这一次就好了

    也就是:

    if(i==x&&j==y)
          f[i][j][x][y]-=a[i][j];    

    这里的减就是数字拿多了,要扣的意思

    然后递推式有两种写法:

    @1:

     f[i][j][x][y]=max(f[i][j][x][y],f[i-1][j][x-1][y]+a[i][j]+a[x][y]);
     f[i][j][x][y]=max(f[i][j][x][y],f[i-1][j][x][y-1]+a[i][j]+a[x][y]);
     f[i][j][x][y]=max(f[i][j][x][y],f[i][j-1][x-1][y]+a[i][j]+a[x][y]);
     f[i][j][x][y]=max(f[i][j][x][y],f[i][j-1][x][y-1]+a[i][j]+a[x][y]);

    第一种递推式的意思是考虑四种走法哪一种好,找出最大的,为每一格附上当前能有的最大数目,一直递推就是答案了

    @2:

    f[i][j][x][y]=a[i][j]+a[x][y]+max(max(max(f[i-1][j][x-1][y],f[i-1][j][x][y-1]),f[i][j-1][x-1][y]),f[i][j-1][x][y-1]);

    第二种和第一种一个意思,写法不同而已

    最后f[n][n][n][n]就是我们要的答案

  • 相关阅读:
    node + express 搭建服务器,修改为自动重启服务器
    在sublime上运行node
    node + express本地搭建服务器,开启一个新的项目
    关于数据库的一些基本操作语句
    8.数据库编程
    2.关于偏函数
    7.多线程编程
    1.关于__call__的很有意思的用法
    6.python中的网络编程
    4.python中常用的魔法方法(长期更新)
  • 原文地址:https://www.cnblogs.com/zyacmer/p/9979364.html
Copyright © 2011-2022 走看看