• USACO 2009 Open Grazing2 /// DP+滚动数组oj26223


    题目大意:

    输入n,s;n头牛 s个栅栏

    输入n头牛的初始位置

    改变他们的位置,满足

    1.第一头与最后一头的距离尽量大

    2.相邻两头牛之间的距离尽量满足 d=(s-1)/(n-1),偏差不超过1

    3.移动的总步数尽量小

    https://blog.csdn.net/BlackJack_/article/details/73527208

    首先因需要尽量满足d

    1.若整除则全部为d即可

    2.若不整除则说明存在偏差,则有些距离 d 有些距离 d+1 即可

    除了第一头牛移到1 最后一头牛移到s之外

    其余第 i 头牛最佳位置应为 d*(i-1)

    若到目前为止位置偏差值为 j ,则应为 d*(i-1)+ j

    则这头牛应该移动 | a[ i ]-(d*(i-1)+j)| 即 abs( a[ i ] - ( i-1 ) * d - j ) 

    那么可由min( dp[ i-1 ][ j ],dp[ i-1 ][ j-1 ] )转移而来

    前者是 i-1 与 i 距离 d 的情况,而后者是 i-1 与 i 距离 d+1 的情况

    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f
    using namespace std;
    int a[1505], dp[2][1505]; // 滚动数组
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&n,&m)) {
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            sort(a+1,a+1+n);
            int d=(m-1)/(n-1);// 最佳间距
            m=m-(n-1)*d;// 总偏差间距+1 (方便推算)
            memset(dp,INF,sizeof(dp));
            /// dp[i][j] 表到第i个时偏差为j的移动次数
            dp[1][1]=a[1]-1;// 偏差从1开始 则m对应的恰好为总偏差间距
            for(int k=2;k<=n;k++) {
                int i=k%2;
                for(int j=1;j<=k&&j<=m;j++)
                    dp[i][j]=min(dp[(!i)][j-1],dp[(!i)][j])
                            +abs(a[k]-(k-1)*d-j);
            }
            printf("%d
    ",dp[n%2][m]);
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    word编号变黑块
    恢复未保存的word
    协方差分析
    SAS字体变大
    可变区组长度--区组随机
    adv and disadv of oncology clinical trial endpoints
    非劣效试验界值确定
    Computer Science
    Compuer Science
    随笔
  • 原文地址:https://www.cnblogs.com/zquzjx/p/9286018.html
Copyright © 2020-2023  润新知