• 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]就是我们要的答案

  • 相关阅读:
    统计次数
    使用正则消除行号
    【收集】sql查询统计,周,月,年
    ASP.NET脚本过滤-防止跨站脚本攻击(收集别人的)
    win10环境下jdk1.8+Android Developer Tools Build: v22.3.0-887826的问题
    关于虚拟机的问题解决(转自豆瓣)
    工作
    numpy学习
    deepin Python pycharm安装
    pymysql连接和操作Mysql数据库
  • 原文地址:https://www.cnblogs.com/zyacmer/p/9979364.html
Copyright © 2020-2023  润新知