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

  • 相关阅读:
    蓝桥杯 矩阵翻硬币
    2018 南京预选赛 J Sum ( 欧拉素数筛 、Square-free Number、DP )
    HDU 3826 Squarefree number ( 唯一分解定理 )
    HDU 5727 Necklace ( 2016多校、二分图匹配 )
    HDU 5726 GCD (2016多校、二分、ST表处理区间GCD、数学)
    hihocoder 1457 后缀自动机四·重复旋律7 ( 多串连接处理技巧 )
    后缀自动机 ( SAM ) 模板
    2018 焦作网络赛 K Transport Ship ( 二进制优化 01 背包 )
    2018 焦作网络赛 G Give Candies ( 欧拉降幂 )
    蓝桥杯 买不到的数目 ( 裴蜀定理 )
  • 原文地址:https://www.cnblogs.com/zyacmer/p/9979364.html
Copyright © 2020-2023  润新知