Codeforces Round - 264 (Div. 2)

C. Gargari and Bishops

题意

选出两个位置,它们的主副对角线之和最大,选过的位置不能重复。

思路

和八皇后问题差不多。i + j和i - j可以表示出在同一斜线上的数字。在读取输入的同时求和。

不能选重复的关键是选(i + j) & 1和是偶数的就行。

代码

#include <bits/stdc++.h>
#define LL long long
#define lowbit(x) ((x) & (-x))
const int MAXN = 2000 + 5;
const int INF = 0x3f3f3f3f;
using namespace std;
 
LL mp[MAXN][MAXN], sum[MAXN * 4];
 
int main()
{
    //freopen("input.txt", "r", stdin);
    int n, i, j;
    scanf("%d", &n);
    for (i = 1; i <= n; i++)
        for (j = 1; j <= n; j++)
        {
            scanf("%lld", [i][j]);
            sum[i + j] += mp[i][j], sum[i - j + 3*n] += mp[i][j];
        }
    LL fans = -1, sans = -1;
    int frow, fcol, srow, scol;
    for (i = 1; i <= n; i++)
        for (j = 1; j <= n; j++)
        {
            LL t = sum[i + j] + sum[i - j + 3*n] - mp[i][j];
            if ((i + j) & 1)
            {
                if (fans < t)
                {
                    fans = t;
                    frow = i, fcol = j;
                }
            }
            else
            {
                if (sans < t)
                {
                    sans = t;
                    srow = i, scol = j;
                }
            }
        }
    printf("%I64d\n", fans + sans);
    printf("%d %d %d %d\n", frow, fcol, srow, scol);
    return 0;
}

D. Gargari and Permutations

题意

求一些排列的最长公共子序列。

思路

参考了别人的思路。可以转化为DAG,然后求最长路!真是奇妙。

代码

#include <bits/stdc++.h>
#define LL long long
#define lowbit(x) ((x) & (-x))
const int MAXN = 1000 + 5;
const int INF = 0x3f3f3f3f;
using namespace std;
 
int ans = 0, pos[6][MAXN], n, k, d[MAXN], vis[MAXN];
vector<int> mp[MAXN];
 
bool Check(int a, int b)    //check if a is behind b
{
    for (int i = 0; i < k; i++)
        if (pos[i][a] > pos[i][b])
            return false;
    return true;
}
 
void SPFA()
{
    queue<int> qu;
    qu.push(0);
    while (!qu.empty())
    {
        int t = qu.front();
        qu.pop();
        vis[t] = 0;
        for (int i = 0; i < mp[t].size(); i++)
        {
            int u = mp[t][i];
            if (d[u] < d[t] + 1)
            {
                d[u] = d[t] + 1;
                ans = max(ans, d[u]);
                if (!vis[u])
                {
                    vis[u] = 1;
                    qu.push(u);
                }
            }
        }
    }
}
 
int main()
{
    //freopen("input.txt", "r", stdin);
    int i, j, temp;
    scanf("%d%d", &n, &k);
    for (i = 0; i < k; i++)
        for (j = 0; j < n; j++)
        {
            scanf("%d", &temp);
            pos[i][temp] = j;
        }
    for (i = 1; i <= n; i++)
    {
        mp[0].push_back(i);
        for (j = i + 1; j <= n; j++)
        {
            if (Check(i, j))
                mp[i].push_back(j);
            else if (Check(j, i))
                mp[j].push_back(i);
        }
    }
    SPFA();
    printf("%d\n", ans);
    return 0;
}

Powered by Jekyll and Theme by solid