zoukankan      html  css  js  c++  java
  • [usaco jan 09] 气象牛 baric [dp]

    题面:

    传送门

    思路:

    题意有点绕,实际上就是给你一个计算规则,让你取最少的元素,通过这个计算方式,得到一个小于指定误差上限的结果

    这个规则分为三个部分,这里分别用pre,sum,suf表示

    因为给定的元素个数(天数)很少,可以使用O(n^3)算法,因此考虑使用经过了预处理的dp解决问题

    具体地,设dp[i][j]表示前i个元素使用了j个且一定取用了第i个时可能达到的最小误差值

    预处理:pre[i]表示通过第一种计算方式得到的,第一个元素取第i个时得到的误差

    suf[i]同理,为第三种计算方式

    sum[i][j]则表示取了i和j且不取中间的元素时,中间的元素产生的误差

    这样dp[i][1]=pre[i],dp[i][j]=dp[k][j-1]+sum[k][i](k=1...i-1),然后用dp[i][j]+suf[j]更新答案即可

    Code:

     1 #include<iostream>
     2 #include<vector>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<algorithm>
     6 #define inf 0x7fffffff/2
     7 using namespace std;
     8 int n,m,a[110];
     9 int dp[110][110]; 
    10 //dp[i][j]: prefix 1-i,chosen j
    11 int pre[110],suf[110],sum[110][110];
    12 int abs(int k){
    13     if(k>=0) return k;
    14     else return -k;
    15 }
    16 int main(){
    17     freopen("baric.in","r",stdin);
    18     freopen("baric.out","w",stdout);
    19     int i,j,k,tmp1,tmp2,t,l;
    20     scanf("%d%d",&n,&m);
    21     int ans=m,anss=n;
    22     for(i=1;i<=n;i++){
    23         scanf("%d",&a[i]);
    24         dp[i][1]=0;
    25     } 
    26     for(i=1;i<=n-2;i++){
    27         for(j=i+2;j<=n;j++){
    28             for(k=i+1;k<j;k++){
    29                 sum[i][j]+=abs((a[k]<<1)-a[i]-a[j]);
    30             }
    31         }
    32     }
    33     for(i=1;i<=n;i++){
    34         for(j=1;j<i;j++) pre[i]+=abs(a[i]-a[j])<<1;
    35         dp[i][1]=pre[i];
    36         for(j=n;j>i;j--) suf[i]+=abs(a[i]-a[j])<<1;
    37     }
    38     for(i=2;i<=n;i++){
    39         for(j=2;j<=i;j++){
    40             dp[i][j]=inf/2;
    41             for(k=1;k<i;k++) dp[i][j]=min(dp[i][j],dp[k][j-1]+sum[k][i]);
    42             if(dp[i][j]+suf[i]<m){
    43                 if(j<ans) ans=j,anss=dp[i][j]+suf[i];
    44                 else if(j==ans&&dp[i][j]+suf[i]<anss) anss=dp[i][j]+suf[i];
    45             }
    46         }
    47     }
    48     printf("%d %d",ans,anss);
    49 } 
  • 相关阅读:
    记第一场省选
    POJ 2083 Fractal 分形
    CodeForces 605A Sorting Railway Cars 思维
    FZU 1896 神奇的魔法数 dp
    FZU 1893 内存管理 模拟
    FZU 1894 志愿者选拔 单调队列
    FZU 1920 Left Mouse Button 简单搜索
    FZU 2086 餐厅点餐
    poj 2299 Ultra-QuickSort 逆序对模版题
    COMP9313 week4a MapReduce
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8457084.html
Copyright © 2011-2022 走看看