绍兴一中模拟赛3.21——孰是孰非
Description
有一个长为
    
     
      
       
        n
       
       
        (
       
       
        n
       
       
        ≤
       
       
        500
       
       
        )
       
      
      
       n(n≤500)
      
     
    n(n≤500)的序列,每次可以选一段区间加上
    
     
      
       
        x
       
      
      
       x
      
     
    x,如果有数大于
    
     
      
       
        7
       
      
      
       7
      
     
    7就减
    
     
      
       
        7
       
      
      
       7
      
     
    7(保持所有数
    
     
      
       
        ∈
       
       
        [
       
       
        1
       
       
        ,
       
       
        7
       
       
        ]
       
      
      
       ∈[1,7]
      
     
    ∈[1,7])
 问:最少几次这样的操作才能使所有
    
     
      
       
        
         a
        
        
         i
        
       
      
      
       a_i
      
     
    ai都等于
    
     
      
       
        7
       
      
      
       7
      
     
    7
Solution
    
     
      
       
        s
       
       
        t
       
       
        e
       
       
        p
       
       
        1
       
       
        :
       
      
      
       step1:
      
     
    step1:先差分一下,令
    
     
      
       
        
         b
        
        
         i
        
       
       
        =
       
       
        
         a
        
        
         i
        
       
       
        −
       
       
        
         a
        
        
         
          i
         
         
          −
         
         
          1
         
        
       
       
        (
       
       
        1
       
       
        ≤
       
       
        i
       
       
        ≤
       
       
        n
       
       
        +
       
       
        1
       
       
        ,
       
       
        
         a
        
        
         0
        
       
       
        =
       
       
        
         a
        
        
         
          n
         
         
          +
         
         
          1
         
        
       
       
        =
       
       
        0
       
       
        )
       
      
      
       b_i=a_i-a_{i-1}(1≤i≤n+1,a_0=a_{n+1}=0)
      
     
    bi=ai−ai−1(1≤i≤n+1,a0=an+1=0)
 每次操作就变成
    
     
      
       
        
         b
        
        
         l
        
       
       
        +
       
       
        x
       
      
      
       b_l+x
      
     
    bl+x,
    
     
      
       
        
         b
        
        
         
          r
         
         
          +
         
         
          1
         
        
       
       
        −
       
       
        x
       
      
      
       b_{r+1}-x
      
     
    br+1−x,目的是让所有
    
     
      
       
        
         b
        
        
         i
        
       
       
        =
       
       
        0
       
      
      
       b_i=0
      
     
    bi=0
 
    
     
      
       
        s
       
       
        t
       
       
        e
       
       
        p
       
       
        2
       
       
        :
       
      
      
       step2:
      
     
    step2:我们发现
    
     
      
       
        1
       
      
      
       1
      
     
    1和
    
     
      
       
        6
       
      
      
       6
      
     
    6是可以一次抵消掉的,同理,
    
     
      
       
        2
       
      
      
       2
      
     
    2和
    
     
      
       
        5
       
      
      
       5
      
     
    5、
    
     
      
       
        3
       
      
      
       3
      
     
    3和
    
     
      
       
        4
       
      
      
       4
      
     
    4也一样
 暴力消的话,也最多消数的个数次就行
 
    
     
      
       
        s
       
       
        t
       
       
        e
       
       
        p
       
       
        3
       
       
        :
       
       
        d
       
       
        p
       
      
      
       step3:dp
      
     
    step3:dp
 因为
    
     
      
       
        1
       
      
      
       1
      
     
    1和
    
     
      
       
        6
       
      
      
       6
      
     
    6、
    
     
      
       
        2
       
      
      
       2
      
     
    2和
    
     
      
       
        5
       
      
      
       5
      
     
    5、
    
     
      
       
        3
       
      
      
       3
      
     
    3和
    
     
      
       
        4
       
      
      
       4
      
     
    4每对都有一个数被抵消掉了,所以
    
     
      
       
        d
       
       
        p
       
      
      
       dp
      
     
    dp状态只要四维就行(第四维是记录当前这些数的和)
 设
    
     
      
       
        f
       
       
        [
       
       
        i
       
       
        ]
       
       
        [
       
       
        j
       
       
        ]
       
       
        [
       
       
        k
       
       
        ]
       
       
        [
       
       
        l
       
       
        ]
       
      
      
       f[i][j][k][l]
      
     
    f[i][j][k][l]表示已经用了
    
     
      
       
        i
       
      
      
       i
      
     
    i个
    
     
      
       
        1
       
       
        /
       
       
        6
       
      
      
       1/6
      
     
    1/6,
    
     
      
       
        j
       
      
      
       j
      
     
    j个
    
     
      
       
        2
       
       
        /
       
       
        5
       
      
      
       2/5
      
     
    2/5,
    
     
      
       
        k
       
      
      
       k
      
     
    k个
    
     
      
       
        3
       
       
        /
       
       
        4
       
      
      
       3/4
      
     
    3/4,总和
    
     
      
       
        m
       
       
        o
       
       
        d
       
       
        7
       
      
      
       mod7
      
     
    mod7为
    
     
      
       
        l
       
      
      
       l
      
     
    l时,最多能少几个步骤,转移见代码
 复杂度
    
     
      
       
        O
       
       
        (
       
       
        7
       
       
        ⋅
       
       
        (
       
       
        
         n
        
        
         6
        
       
       
        
         )
        
        
         3
        
       
       
        )
       
      
      
       O(7\cdot(\frac{n}{6})^3)
      
     
    O(7⋅(6n)3)
Code
#include<bits/stdc++.h>
using namespace std;
int n,x,y,z,i,mx,my,mz,l,j,k,a[8],f[2][502][502][7],las,ans,p;
void Max(int &x,int y){if(y>x)x=y;}
int main(){
	scanf("%d",&n);
	for (i=1;i<=n;i++){
		scanf("%d",&x);
		a[(x-las+7)%7]++,las=x;
	}
	a[7-las]++;
	if (a[1]>a[6]) x=1,swap(a[1],a[6]);
	else x=6;
	if (a[2]>a[5]) y=2,swap(a[2],a[5]);
	else y=5;
	if (a[3]>a[4]) z=3,swap(a[3],a[4]);
	else z=4;
	ans=a[4]+a[5]+a[6];
	mx=a[6]-a[1],my=a[5]-a[2],mz=a[4]-a[3];
	for (i=0;i<=mx;i++,p^=1)
		for (j=0;j<=my;j++)
			for (k=0;k<=mz;k++)
				for (l=0;l<7;l++)
				Max(f[p^1][j][k][(l+x)%7],f[p][j][k][l]+(l+x==7)),
				Max(f[p][j+1][k][(l+y)%7],f[p][j][k][l]+(l+y==7)),
				Max(f[p][j][k+1][(l+z)%7],f[p][j][k][l]+(l+z==7));
	printf("%d",ans-f[p^1][my][mz][0]);
}
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号