[ABC203F]Weed
Weed
题解
简单dp
很容易发现,由于Takahashi每次都会使最高高度减小一半,所以Takahashi的操作数不会超过 
     
      
       
       
         l 
        
       
         o 
        
       
         g 
         
       
         a 
        
       
      
        log \,a 
       
      
    loga。
 于是我们就很容易想到 
     
      
       
       
         d 
        
       
         p 
        
       
      
        dp 
       
      
    dp,先将 
     
      
       
       
         a 
        
       
      
        a 
       
      
    a排序,定义 
     
      
       
       
         d 
        
        
        
          p 
         
         
         
           i 
          
         
           , 
          
         
           j 
          
         
        
       
      
        dp_{i,j} 
       
      
    dpi,j表示对于前 
     
      
       
       
         i 
        
       
      
        i 
       
      
    i个点,使用Takahashi操作 
     
      
       
       
         j 
        
       
      
        j 
       
      
    j次就能将其全部剪完所需要的Aoki最小操作次数。
 设第一个不大于 
     
      
       
        
         
         
           a 
          
         
           i 
          
         
        
          2 
         
        
       
      
        \frac{a_{i}}{2} 
       
      
    2ai的点为 
     
      
       
       
         k 
        
       
         , 
        
       
      
        k, 
       
      
    k,容易得到转移:
  
      
       
        
        
          d 
         
         
         
           p 
          
         
           i 
          
         
        
          = 
         
         
          
          
            min 
           
          
             
           
          
          
          
            j 
           
          
            = 
           
          
            1 
           
          
         
           k 
          
         
        
          ( 
         
        
          d 
         
         
         
           p 
          
         
           j 
          
         
        
          + 
         
        
          k 
         
        
          − 
         
        
          j 
         
        
          ) 
         
        
          = 
         
         
          
          
            min 
           
          
             
           
          
          
          
            j 
           
          
            = 
           
          
            1 
           
          
         
           k 
          
         
        
          ( 
         
        
          d 
         
         
         
           p 
          
         
           j 
          
         
        
          − 
         
        
          j 
         
        
          ) 
         
        
          + 
         
        
          k 
         
        
       
         dp_{i}=\min_{j=1}^{k}(dp_{j}+k-j)=\min_{j=1}^{k}(dp_{j}-j)+k 
        
       
     dpi=j=1mink(dpj+k−j)=j=1mink(dpj−j)+k
 很容易看出来,这个 
     
      
       
       
         d 
        
       
         p 
        
       
      
        dp 
       
      
    dp转移可以采用前缀和进行优化。
 所以我们找到使得 
     
      
       
       
         ∃ 
         
       
         i 
        
       
         , 
        
       
         d 
        
        
        
          p 
         
         
         
           i 
          
         
           , 
          
         
           j 
          
         
        
       
         + 
        
       
         n 
        
       
         − 
        
       
         i 
        
       
         ⩽ 
        
       
         k 
        
       
      
        \exists \,i,dp_{i,j}+n-i\leqslant k 
       
      
    ∃i,dpi,j+n−i⩽k的最小的 
     
      
       
       
         j 
        
       
      
        j 
       
      
    j就可以了。
时间复杂度 O ( n l o g a ) O\left(nlog\,a\right) O(nloga)。
源码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
#define lowbit(x) (x&-x)
#define reg register
#define mkpr make_pair
#define fir first
#define sec second
typedef long long LL;
typedef unsigned long long uLL;
const int INF=0x3f3f3f3f;
const int mo=1e9+7;
const int zero=500;
const LL jzm=2333;
const int orG=3,invG=332748118;
const double Pi=acos(-1.0);
typedef pair<int,int> pii;
const double PI=acos(-1.0);
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
int add(int x,int y){return x+y<mo?x+y:x+y-mo;}
int n,k,a[MAXN],dp[MAXN][35],pre[MAXN][35],ans,ansp;
signed main(){
	read(n);read(k);
	for(int i=1;i<=n;i++)read(a[i]);
	if(n<=k){printf("%d %d\n",0,n);return 0;}
	sort(a+1,a+n+1);ans=30;
	for(int i=0;i<=30;i++)pre[0][i]=n;
	for(int i=1;i<=n;i++){
		int l=0,r=i-1;while(l<r){int mid=l+r+1>>1;if(a[mid]*2<=a[i])l=mid;else r=mid-1;}
		pre[i][0]=pre[i-1][0];
		for(int j=1;j<=30;j++){
			dp[i][j]=pre[l][j-1]-(n-l);
			pre[i][j]=min(pre[i-1][j],dp[i][j]+n-i);
		}
		for(int j=1;j<=30;j++)
			if(dp[i][j]+n-i<=k&&(j<ans||(j==ans&&ansp>dp[i][j]+n-i)))
				ans=j,ansp=dp[i][j]+n-i;
	}
	printf("%d %d\n",ans,ansp);
	return 0;
}
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号