Codeforces 500B New Year Permutation Floyd算法+贪心

题目链接


题意:给出一个数列(n<=300),Permutation a1, a2, …, an is prettier than permutation b1, b2, …, bn, if and only if there exists an integer k (1 ≤ k ≤ n) where a1 = b1, a2 = b2, …, ak - 1 = bk - 1 and ak < bk all holds。然后给出一张表,告诉你每一次可将哪两个元素可以交换。输出最优排列。



解法:先用floyd求出每个元素经过一定次数的交换可以和哪个元素换位置,然后用贪心求解,保证最左边的数尽量小。


code:

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;

#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
#define mes(a,x,s)  memset(a,x,(s)*sizeof a[0])
#define mem(a,x)  memset(a,x,sizeof a)
#define ysk(x)  (1<<(x))
typedef long long ll;
//const int INF = 0x3f3f3f3f ;
const int maxn= 300 ;
int n,a[maxn+3];
bool dp[maxn+3][maxn+3];

void floyd()
{
    for1(i,n)  dp[i][i]=1;

    for(int k=1;k<=n;k++)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                dp[j][i]=dp[i][j]= dp[i][j]|| dp[i][k]&&dp[k][j];
            }
        }

    }

}


void greedy()
{
    for1(i,n) 
    {
        int k=i;
        for(int j=i+1;j<=n;j++) if(a[j]<a[k]&&dp[i][j])
        {
            k=j;
        }

        if(k!=i) swap(a[i],a[k]);
    }

    for1(i,n)
    {
        printf("%d%c",a[i],i==n?'\n':' ');
    }

}
int main()
{
    scanf("%d",&n);
    for1(i,n)  scanf("%d",&a[i]);
    char ch;
    for1(i,n) for1(j,n) 
    {
        scanf(" %c",&ch);
        dp[i][j]= ch=='1'?1:0;
    }
    floyd();
    greedy();

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值