arc 166 b

#include<bits/stdc++.h>
using namespace std;
using VI = vector<int>;
using ll = long long;
using PII = pair <ll , int>;
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<<calc(8 , 2 , 0);
    cout<<dp[1][2];*/
    cout<<dp[n][7];


}

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值