[USACO 6.3.3] Cowcycles

题目大意

  有长度为F和R的两个数组.F数组可以选择F1~F2的数放进去,R数组可以选择R1~R2的数放进去.

  此时,F数组任意选择一个数除以R数组的任意一个数,这样就会形成一个新的长度为F*R的数列并求这个数列的方差.

  我们要选出这样的F和R数组使得形成的F*R的数列的方差最小.

题解

  直接暴搜即可.因为USACO的数据很蒻.

代码

 

/*
TASK:cowcycle
LANG:C++
*/

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int F, R, f1, f2, r1, r2, minfr, maxfr, minbk, maxbk;
int ansfr[5], ansbk[10];
int tmpfr[5], tmpbk[10];
double minvar;

double variance()
{
    double d[50], aver = 0, vari = 0;
    int n = 0;
    for (int i = 0; i < F; ++i)
        for (int j = 0; j < R; ++j)
            d[n++] = (double)tmpfr[i] / tmpbk[j];
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < i; ++j)
            if (d[i] < d[j]) swap(d[i], d[j]);
    for (int i = 0; i < n - 1; ++i)
        d[i] = d[i + 1] - d[i], aver += d[i] / (n - 1);
    n--;
    for (int i = 0; i < n; ++i)
        vari += (d[i] - aver) * (d[i] - aver) / n;
    return vari;
}

bool judge(double vrc)
{
    if (vrc < minvar) return true;
    else if (vrc > minvar) return false;
    for (int i = 0; i < F; ++i)
        if (tmpfr[i] < ansfr[i]) return true;
        else if (tmpfr[i] > ansfr[i]) return false;
    for (int i = 0; i < R; ++i)
        if (tmpbk[i] < ansbk[i]) return true;
        else if (tmpbk[i] > ansbk[i]) return false;
    return false;
}

void dfsbk(int s)
{
    if (s >= R - 1)
    {
        double vrc = variance();
        if (judge(vrc))
        {
            memcpy(ansfr, tmpfr, F * sizeof(int));
            memcpy(ansbk, tmpbk, R * sizeof(int));
            minvar = vrc;
        }
        return;
    }
    for (int i = tmpbk[s-1] + 1; i <= tmpbk[R-1] - R + s + 1; ++i)
    {
        tmpbk[s] = i;
        dfsbk(s + 1);
    }
}

void dfsfr(int s)
{
    if (s >= F - 1)
    {
        dfsbk(1);
        return;
    }
    for (int i = tmpfr[s-1] + 1; i <= tmpfr[F-1] - F + s + 1; ++i)
    {
        tmpfr[s] = i;
        dfsfr(s + 1);
    }
}

int main()
{
    freopen("cowcycle.in", "r", stdin);
    freopen("cowcycle.out", "w", stdout);
    scanf("%d%d%d%d%d%d", &F, &R, &f1, &f2, &r1, &r2);
    minvar = 1.0 * 0x7fffffff;
    for (minfr = f1; minfr <= f2 - F + 1; ++minfr)
        for (maxfr = minfr + F - 1; maxfr <= f2; ++maxfr)
            for (minbk = r1; minbk <= r2 - R + 1; ++minbk)
                for (maxbk = minbk + R - 1; maxbk <= r2; ++maxbk)
                    if (maxfr * maxbk >= minfr * minbk * 3)
                    {
                        tmpfr[0] = minfr;
                        tmpfr[F-1] = maxfr;
                        tmpbk[0] = minbk;
                        tmpbk[R-1] = maxbk;
                        dfsfr(1);
                    }
    for (int i = 0; i < F - 1; ++i) printf("%d ", ansfr[i]);
    printf("%d\n", ansfr[F-1]);
    for (int i = 0; i < R - 1; ++i) printf("%d ", ansbk[i]);
    printf("%d\n", ansbk[R-1]);
    return 0;
}

 

posted @ 2016-08-04 12:07  albertxwz  阅读(249)  评论(0编辑  收藏  举报