ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

这次应该叫高二上几调?

2022-07-14 19:34:39  阅读:137  来源: 互联网

标签:几调 maxx ch 高二上 这次 max ll int maxn


B. biology

错误思路:按a的值分个层,直接把每层的最大值的点编号放到队列里,后来忽然发现每个a最小一层的点都有可能当一次起点,它的位置决定了后面的点的位置,不能单独考虑起点b值的大小,于是就让每一个最小的a当一次起点循环一遍。我已经做好了它超时的心理准备,但是有WA的点就不太理解。。。如果有读者能指出错因我会很感谢的。

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 4e6 + 3;
const int N = 1e7 + 2;
const ll INF = 1e17;

int n, m, q[maxn], l=1, r, num, pos, hv[maxn], cnt;
ll ans;
struct node
{
    int x, y, a, b;
    bool operator < (const node &T)
    {
        return a < T.a;
    }
}p[maxn];

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch > '9' || ch < '0')
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}

int main()
{
    n = read(); m = read();
    //printf("n=%d m=%d\n", n, m);
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m ;j++)
        {
            p[++num].a = read();
            //printf("p[%d].a = %d\n", num, p[num].a);
            p[num].x = i; p[num].y = j;
        }
    }
    num = 0;
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            p[++num].b = read();
        }
    }
    sort(p+1, p+1+num);
    //printf("%d", p[1].a);
    for(int i=1; i<=num; i++)
    {
        if(p[i].a)
        {
            pos = i; break;
        }
    }
    q[++r] = pos;
    hv[++cnt] = pos;
    for(int i=pos+1; i<=num; i++)
    {
        //printf("p[%d].a = %d\n", i, p[i].a);
        //printf("cmp : %d %d\n", p[i].a, p[q[1]].a);
        if(p[i].a == p[q[1]].a) 
        {
            hv[++cnt] = i;
            pos = i;
        }
        else break;
    }
    //printf("cnt=%d\n", cnt);
    for(int k=1; k<=cnt; k++)
    {
        ll sum = 0;
        l = 1, r = 0;
        q[++r] = hv[k];
        for(int i=pos+1; i<=num; i++)
        {
            if(p[i].a > p[q[r]].a) q[++r] = i;
            else if(p[i].a == p[q[r]].a)
            {
                if(r == 1)
                {
                    continue;
                }
                else if((ll)p[i].b+abs(p[i].x-p[q[r-1]].x)+abs(p[i].y-p[q[r-1]].y) > (ll)p[q[r]].b+abs(p[q[r]].x-p[q[r-1]].x)+abs(p[q[r]].y-p[q[r-1]].y))
                {
                    q[r] = i;
                }
            }
        }
        sum += p[q[1]].b;
        for(int i=2; i<=r; i++)
        {
            sum += (ll)p[q[i]].b+abs(p[q[i]].x-p[q[i-1]].x)+abs(p[q[i]].y-p[q[i-1]].y);
        }
        //printf("sum=%lld\n", sum);
        ans = max(ans, sum);
    }
    /*for(int i=pos+1; i<=num; i++)
    {
        if(p[i].a > p[q[r]].a) q[++r] = i;
        else if(p[i].a == p[q[r]].a)
        {
            if(r == 1)
            {
                if(p[i].b > p[q[r]].b) q[r] = i;
            }
            else if((ll)p[i].b+abs(p[i].x-p[q[r-1]].x)+abs(p[i].y-p[q[r-1]].y) > (ll)p[q[r]].b+abs(p[q[r]].x-p[q[r-1]].x)+abs(p[q[r]].y-p[q[r-1]].y))
            {
                q[r] = i;
            }
        }
    }*/
    /*ans += p[q[1]].b;
    for(int i=2; i<=r; i++)
    {
        ans += (ll)p[q[i]].b+abs(p[q[i]].x-p[q[i-1]].x)+abs(p[q[i]].y-p[q[i-1]].y);
    }*/
    printf("%lld", ans);

    return 0;
}
只有30分

然后就是题解了:

第一步还是分层,但这个分层是放到数组里,而不是在脑海中。预处理的标准是每一个层号都能找到这一层的数值,而每一层的数值也能对应回层的编号。

dp[i][j] 表示当前路径的结尾在(i, j)位置的最大吸引度之和。 f[i][j] = max{f[i'][j'] + b[i'][j'] + ∣i − i ∣ + ∣j − j ∣, a[i][j] = a[i'][j'] + x, x>=1} 。

把绝对值拆开:f[i][j]可能为f[i'][j']+b[i'][j']-i'-j'+i+j或f[i'][j']+b[i'][j']+i'+j'-i-j或f[i'][j']-i'+j'+i-j或f[i'][j']+i'-j'+i+j。所以坐标转换,把(i+j, i-j)放进a[i][j]属于的分层,再用四个变量维护一下i'和j'的四种对应情况随递推的变化,递推时对应决定了当前的i和j应该加还是应该减。

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 2e3 + 2;
const int N = 4e6 + 3;
const ll INF = 1e17;

int a[maxn][maxn], b[maxn][maxn], n, m;
int rec[N], pos[N], cnt;
ll dp[maxn][maxn], ans, maxx[5];
bool vis[N];
vector<pair<int, int> > v[N];

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch > '9' || ch < '0')
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}

int main()
{
    n = read(); m = read();
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            a[i][j] = read();
            if(!a[i][j]) continue;
            if(!vis[a[i][j]]) rec[++cnt] = a[i][j];
            vis[a[i][j]] = 1;
        }
    }
    sort(rec+1, rec+1+cnt);
    for(int i=1; i<=cnt; i++) pos[rec[i]] = i;
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            b[i][j] = read();
        }
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            if(!a[i][j]) continue;
            v[pos[a[i][j]]].push_back(make_pair(i+j, i-j));
        }
    }
    for(int i=0; i<(int)v[1].size(); i++)
    {
        ll p = v[1][i].first, q = v[1][i].second;
        ll valb = b[(p+q)>>1][(p-q)>>1];//用原坐标的b值
        maxx[1] = max(maxx[1], valb-p);
        maxx[2] = max(maxx[2], valb+p);
        maxx[3] = max(maxx[3], valb-q);
        maxx[4] = max(maxx[4], valb+q);
    }
    for(int i=2; i<=cnt; i++)
    {
        for(int j=0; j<(int)v[i].size(); j++)
        {
            ll p = v[i][j].first, q = v[i][j].second;
            ll valb = b[(p+q)>>1][(p-q)>>1];
            //b'-i'-j'+b+i+j
            //b'+i'+j'+b-i-j
            //b'-i'+j'+b+i-j
            //b'+i'-j'+b-i+j
            dp[(p+q)>>1][(p-q)>>1] = max(max(maxx[1]+valb+((p+q)>>1)+((p-q)>>1),
                                             maxx[2]+valb-((p+q)>>1)-((p-q)>>1)),
                                         max(maxx[3]+valb+((p+q)>>1)-((p-q)>>1),
                                             maxx[4]+valb-((p+q)>>1)+((p-q)>>1)));
        }
        for(int j=0; j<(int)v[i].size(); j++)
        {
            ll p = v[i][j].first, q = v[i][j].second;
            ll valdp = dp[(p+q)>>1][(p-q)>>1];
            maxx[1] = max(maxx[1], valdp-p);//b-i-j
            maxx[2] = max(maxx[2], valdp+p);
            maxx[3] = max(maxx[3], valdp-q);
            maxx[4] = max(maxx[4], valdp+q);
        }
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            ans = max(ans, dp[i][j]);
        }
    }
    printf("%lld\n", ans);

    return 0;
}
感谢WR大佬

 

标签:几调,maxx,ch,高二上,这次,max,ll,int,maxn
来源: https://www.cnblogs.com/Catherine2006/p/16479034.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有