现在的位置: 首页 > 综合 > 正文

杭电1421

2014年01月23日 ⁄ 综合 ⁄ 共 2016字 ⁄ 字号 评论关闭

题意:

求n个数中k组数,每组2个数,使得每组数之差的平方和最小。

TLE的代码:

思想:1 先排序,把相同的处理掉,并标记被处理的位置,然后遍历数组,每次找未被处理的数据中两个数之差最小的数,加到ans中,直到得到k组数据。很遗憾,被TLE了。

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int a[2005];
int v[1<<15];
int main()
{
    int n,k;
    while(cin>>n>>k)
    {
        memset(v,0,sizeof(v));
        for(int i=0; i<n; ++i)
            cin>>a[i];
        sort(a,a+n);
        int ans=0;
        for(int i=0; i<=n-2; i+=2)
        {
            if(a[i]==a[i+1])
            {
                ans++;
                v[i]=1;
                v[i+1]=1;
            }
            else
            {
                i=i-1;
            }
            if(ans==k)
            {
                break;
            }
        }
        k=k-ans;
        if(k==0)
        {
            cout<<0<<endl;
            continue;
        }
        //cout<<k<<endl;
        int m,nn,min=1000,tem,anss=0;
        for(int i=1; i<=k; ++i)
        {
            min=1000;
            for(int j=0; j<n-1;)
            {
                if(v[j]==0)
                    for(int l=j+1; l<n; ++l)
                    {
                        if(v[l]==0)
                        {
                            tem=a[l]-a[j];
                            if(tem<min)
                            {
                                min=tem;
                                m=j;
                                nn=l;
                            }
                            j=l;
                            break;
                        }
                    }
            }
            v[m]=1;
            v[nn]=1;
            anss+=min*min;
            //cout<<min<<endl;
        }
        cout<<anss<<endl;
        //cout<<min<<endl;
    }
    return 0;
}

dp代码:

dp思维就是找状态方程,dp[i][j]=min(dp[i][j-1],dp[i-1][j-2]+(a[j]-a[j-1])*(a[j]-a[j-1])),就是dp[m][2*m]的值是可以确定的,可以找到dp[m][2*m+1]与dp[m][2*m],dp[m-1][2*m-1]的关系。

#include<iostream>
#include<string.h>
#include<algorithm>
#define N 2005
using namespace std;
int a[N];
int dp[N/2][N];
//初始化
void init(int k)
{
    int aa=0;
    for(int i=2; i<=2*k; i+=2)
    {
        aa+=(a[i]-a[i-1])*(a[i]-a[i-1]);
        dp[i/2][i]=aa;
    }
}

//dp方程     dp[i][j]=min(dp[i][j-1],dp[i-1][j-2]+(a[j]-a[j-1])*(a[j]-a[j-1]));
int work(int n,int m)
{
    init(m);
    for(int i=1; i<=m; i++)
    {
        for(int j=2*i+1; j<=n; j++)
        {
            dp[i][j]=min(dp[i][j-1],dp[i-1][j-2]+(a[j]-a[j-1])*(a[j]-a[j-1]));
        }
    }
    return dp[m][n];
}
int main()
{
    int n,k;
    while(cin>>n>>k)
    {
        memset(dp,0,sizeof(dp));
        for(int i=1; i<=n; ++i)
            cin>>a[i];
        sort(a+1,a+n+1);
        int ans;
        ans=work(n,k);
        cout<<ans<<endl;
    }
    return 0;
}

抱歉!评论已关闭.