arc 166 b

#include
using namespace std;
using VI = vector;
using ll = long long;
using PII = pair ;
const int mod = 998244353;
int n;
//第 i 个字母 状态为 j 的操作次数
//dp[i][j] = dp[i-1][k]

ll a[200050];
ll dp[200050][8];//x  y   z
ll x,y,z,xy,xz,yz,xyz;

ll calc(ll h, int cur , int pre){
    //1 0
    //0 1
    //0 1
    int g[3] = {0,0,0};
    for(int i = 0 ; i <= 2 ; i++){
        if((cur>>i) & 1 && ((pre>>i) & 1) == 0){
            g[i] = 1;
        }
    }
    ll t;
    //3 4
    //
    if(g[0] == 0 && g[1] == 0 && g[2] == 0){
        t = 0;
    }else if(g[0] == 1 && g[1] == 0 && g[2] == 0){
        t = x - h % x;
        t %= x;
    }else if(g[0] == 1 && g[1] == 1 && g[2] == 0){
        t = xy - h % xy;
        t %= xy;
    }else if(g[0] == 1 && g[1] == 1 && g[2] == 1){
        t = xyz - h % xyz;
        t %= xyz;
    }else if(g[0] == 0 && g[1] == 1 && g[2] == 0){
        t = y - h % y;
        t %= y;
    }else if(g[0] == 0 && g[1] == 1 && g[2] == 1){
        t = yz - h % yz;
        t %= yz;
    }else if(g[0] == 0 && g[1] == 0 && g[2] == 1){
        t = z - h % z;
        t %= z;
    }else if(g[0] == 1 && g[1] == 0 && g[2] == 1){
        t = xz - h % xz;
        t %= xz;
    }
    return t;



}



int main(){
    cin>>n>>x>>y>>z;
    xy = x * y / __gcd(x,y);
    xz = x * z / __gcd(x,z);
    yz = z * y / __gcd(z,y);
    xyz = xy * z / __gcd(xy,z);
    for(int i = 1 ; i <= n ; i++) cin>>a[i];

    for(int i = 0 ; i <= n ; i++){
        for(int j = 0 ; j <= 7 ; j++){
            dp[i][j] = 1e18;
        }
        dp[i][0] = 0;
    }
    for(int i = 1 ; i <= n ; i++){
        for(int j = 0 ; j <= 7 ; j++){
            for(int k = 0 ; k <= 7 ; k++){
                dp[i][j] = min(dp[i][j] , dp[i-1][k] + calc(a[i] , j , k));
            }
        }
    }
   /* cout<

和网络赛没做出来的dp挺像的

类似就是状态枚举 , 考虑每个状态的花费 , 然后直接转移

你可能感兴趣的:(dp,算法,c++,数据结构)