列表

详情


NC19774. 数据排序

描述

机器学习通常需要用到大量的人工标注好的数据进行训练。现在有这么一个数据集,有 N 个张照片,每张照片中都有一个模特。某个研究员想要训练一个机器学习算法,能够根据照片对模特的魅力值进行评分。为了完成这个算法,研究员找了若干个志愿者对数据做一个标注。每个志愿者每次会看到系统给出的两张照片 x 和 y,然后告诉系统他认为哪张照片的魅力值更高。例如 x 的魅力值比 y 的要高(记作 <x, y>)这样一个有序二元组称之为一个数标注。
研究员收集了若干个这样的数据标注,他想找到一组对每张照片的评分 c1, ..., cn,使得这个评分和数据的冲突越少越好。为了方便设定N 张照片所组成的 对照片都分别有 4 个记录,也就是被标注了 4 次。定义 g(x, y) 为记录<x, y>出现的次数,定义评分 {cn} 的冲突值:

你需要求出在这个数据集下冲突值 f(c) 的最小值。

输入描述

第一行一个整数 N,表示数据集大小。
接下来 2N(N-1) 行,每一行都有两个整数 xi, yi ,表示第 i 组数据标注 < xi, yi >.

输出描述

输出一个整数,冲突值的最小值。

示例1

输入:

2
1 2
1 2
2 1
1 2

输出:

1

说明:

如果这两个数据得分相同,则冲突值为2;如果 1 比 2 得分高,则冲突值为1;如果 2 比 1 得分高,则冲突值为 3. 所以冲突值的最小值为1.

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 288ms, 内存消耗: 1132K, 提交时间: 2018-10-02 13:07:26

#include<bits/stdc++.h>
using namespace std;
int b[15][15],n,m,i,j,k,l,d[32768],f[32768],g[32768],o[32768],a[32768];
int A(int x)
{
    if(x<0)return -x;
    return x;
}
int main()
{
    scanf("%d",&n);
    for(i=0;i<n*(n-1)*2;i++)
    {
        scanf("%d%d",&j,&k);
        if(j&&k)b[j-1][k-1]++;
    }
    for(i=1;i<n;i++)o[1<<i]=i;
    for(i=1;i<1<<n;i++)for(d[i]=d[i^(i&-i)],j=0;j<n;j++)if((i^(i&-i))>>j&1)d[i]+=A(b[j][o[i&-i]]-b[o[i&-i]][j]);
    memset(f,127,sizeof(f));
    for(f[0]=i=0;i<1<<n;i++)
    {
        for(j=m=(1<<n)-1^i,k=0;j;j=j-1&m)a[k++]=j;
        reverse(a,a+k);
        for(j=0;j<k;j++)
        {
            for(g[a[j]]=g[a[j]^(a[j]&-a[j])],l=0;l<n;l++)if(i>>l&1)g[a[j]]+=b[l][o[a[j]&-a[j]]];
            f[i^a[j]]=min(f[i^a[j]],f[i]+g[a[j]]+d[a[j]]);
        }
    }
    cout<<f[(1<<n)-1]<<endl;
    return 0;
}

C++14(g++5.4) 解法, 执行用时: 473ms, 内存消耗: 988K, 提交时间: 2018-10-02 20:18:22

#include<bits/stdc++.h>
using namespace std;
int b[15][15],n,m,i,j,k,l,d[32768],f[32768],g[32768],o[32768],a[32768];
int A(int x) {
	if(x<0)return -x;
	return x;
}
int main() {
	scanf("%d",&n);
	for(i=0; i<n*(n-1)*2; i++) 
	{
		scanf("%d%d",&j,&k);
			b[j-1][k-1]++;
	}
	for(i=1; i<n; i++)
		o[1<<i]=i;
		
	for(i=1; i<1<<n; i++)
		for(d[i]=d[i^(i&-i)], j=0; j<n; j++)
			if((i^(i&-i))>>j&1)
				d[i]+=A(b[j][o[i&-i]]-b[o[i&-i]][j]);
				
	memset(f,127,sizeof(f));
	
	for(f[0]=i=0; i<1<<n; i++) 
	{
		for(j=m=(1<<n)-1^i,k=0; j; j=j-1&m)
			a[k++]=j;
		reverse(a,a+k);
		for(j=0; j<k; j++) 
		{
			for(g[a[j]]=g[a[j]^(a[j]&-a[j])],l=0; l<n; l++)
				if(i>>l&1)g[a[j]]+=b[l][o[a[j]&-a[j]]];
				
			f[i^a[j]]=min(f[i^a[j]],f[i]+g[a[j]]+d[a[j]]);
		}
	}
	
	cout<<f[(1<<n)-1]<<endl;
	return 0;
} 

上一题