• bzoj3405:[Usaco2009 Open]Grazing2 移动牛棚


    思路:首先因为要让距离尽量大,所以奶牛1一定在1号牛棚,奶牛n一定在s号牛棚,然后考虑dp。

    因为总距离为s-1,然后要使长度为d的段数尽量多,那么剩下的一定就是d+1的段数,也就是s-(n-1)*d。

    然后f[i][j]表示保证前i个牛棚合法且前面长为d+1的段数为j的答案,然后第i个牛棚的位置其实就是(i-1)*d+j。

    又因为第i-1个牛棚只可能是相隔d或d-1,所以有f[i][j]=min(f[i-1][j],f[i-1][j-1])+abs(a[i]-(i-1)*d-j)

    答案就是f[n][m]。

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define maxn 1505
     
    int n,s;
    int a[maxn];
    int f[maxn][maxn];
     
    inline int read(){
        int x=0;char ch=getchar();
        for (;ch<'0'||ch>'9';ch=getchar());
        for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
        return x;
    }
     
    inline void print(int x){
        if (x>=10) print(x/10);
        putchar(x%10+'0');
    }
     
    int main(){
        n=read(),s=read();int d=(s-1)/(n-1),m=s-(n-1)*d;
        for (int i=1;i<=n;i++) a[i]=read();
        sort(a+1,a+n+1);
        memset(f,63,sizeof(f)),f[1][1]=a[1]-1;
        for (int i=2;i<=n;i++)
            for (int j=1;j<=m&&j<=i;j++)
                f[i][j]=min(f[i-1][j],f[i-1][j-1])+abs(a[i]-d*(i-1)-j);
        print(f[n][m]);
        return 0;
    }
  • 相关阅读:
    2019秋季 关于C语言指针等探索
    第四次作业
    第三次作业
    错误总结
    第二次作业
    第一次随笔
    Linux Mint安装Docker踩坑指南
    浅论Javascript在汽车信号测试中的应用
    [瞎玩儿系列] 使用SQL实现Logistic回归
    MongoDB的账户与权限管理及在Python与Java中的登录
  • 原文地址:https://www.cnblogs.com/DUXT/p/6049016.html
Copyright © 2020-2023  润新知