luogu 2943 [USACO09MAR]清理Cleaning Up 动态规划

非常巧妙的动态规划. 

你会发现每一个区间地颜色种类不能超过 $sqrt n$, 所以可以直接枚举区间颜色种类. 

令这个为 $pos[j],$ 然后考虑如何去更新这个东西就行了. 

Code: 

#include <bits/stdc++.h>  
#define N 40004 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;  
int p[N],lst[N],nex[N],pos[N],cn[N],f[N],cnt[N];            
int main() 
{ 
    int i,j,n,m; 
    // setIO("input");  
    scanf("%d%d",&n,&m); 
    for(i=1;i<=n;++i) 
    {
        scanf("%d",&p[i]);  
        lst[i]=0, nex[i]=n+1;   
        if(cn[p[i]]) 
        {
            nex[cn[p[i]]]=i;            
            lst[i]=cn[p[i]];                 
        } 
         cn[p[i]]=i;  
        f[i]=1000000006;         
    }    
    int t=sqrt(n);     
    for(i=1;i<=n;++i) pos[i]=1;
    f[0]=0;     
    for(i=1;i<=n;++i) 
    {
        for(j=1;j<=t;++j) 
        {
            if(lst[i]<pos[j]) ++cnt[j];    
            if(cnt[j]>j) 
            {
                --cnt[j];    
                for(;nex[pos[j]]<i;) ++pos[j];      
                ++pos[j];                                 
            }
            f[i]=min(f[i], f[pos[j]-1]+(j*j));                     
        }
    }
    printf("%d
",f[n]); 
    return 0; 
}

  

原文地址:https://www.cnblogs.com/guangheli/p/11606490.html