首页 > 其他分享 >HDU多校-交通管控

HDU多校-交通管控

时间:2024-08-06 14:27:45浏览次数:8  
标签:60050 状态 HDU 管控 int 多校 long bi dp

Problem - 7498 (hdu.edu.cn)

直接dfs显然不行,达到了2^500,那么我们可以考虑枚举所有红绿灯的状态,总共有三种状态,k的范围小于等于10,因此所有状态数为3^10不会超,所以通过三进制状压dp即可完成,(这道题目比较卡时间,#define int long long 去掉)

dp开二维,第一维记录前一种状态,第二维记录所有红绿灯状态,通过mp来判断前一种状态是否存在。

#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f3f3f3f3f;
const int N = 2e5+5;
char a[505][15];
int dp[5][60050];//i有0,1两种状态,标记前一种状态是否存在
int mp[5][60050];
int bi[25];
int n,k,mod;

void solve(){
	cin>>n>>k>>mod;
    int m = bi[k];
    for(int i=1;i<=n;i++){
        for(int j=0;j<k;j++){
            cin>>a[i][j];
        }
    }

    for(int i=1;i<=m;i++){
        dp[0][i]=0;
        dp[1][i]=0;
        mp[0][i]=0;
        mp[1][i]=0;
    }
    dp[0][0] = 1;
    mp[0][0] = 1;

    for(int i=1;i<=n;i++){
        for(int j=m-1;j>=0;j--){//三进制枚举所有状态
            int s = j;
            for(int p=0;p<k;p++){
                int num = s/bi[p];
                int kk = num % 3LL;
                s -= bi[p] * kk;
                if(a[i][p]=='-'){//反向减去,查找前一种状态
                    kk = (kk+1)%3LL;
                }
                else if(a[i][p]=='+'){
                    kk = (kk+2)%3LL;
                }
                s += bi[p] * kk;
            }
            if(mp[(i+1)%2][s]||mp[(i+1)%2][j])mp[i%2][j] = 1;//用或不用
            dp[i%2][j] = (dp[(i+1)%2][j] + dp[(i+1)%2][s]) % mod;
        }
    }

    map<string,int>mpp;

    for(int i=0;i<=m-1;i++){
        string ss;//字符串枚举
        if(mp[(n%2)][i]==0)continue;
        for(int j=0;j<k;j++){
            int num = i / bi[j];
            int yu = num%3;
            if(yu == 0)ss+='A';
            else if(yu == 1)ss+='B';
            else ss += 'C';
        }
        mpp[ss] = (dp[(n%2)][i])%mod;
    }

    for(auto &t:mpp){
        cout<<t.first<<" "<<t.second<<"\n";
    }

}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    
    bi[0] = 1;
    for(int i=1;i<=10;i++){
        bi[i] = bi[i-1] * 3LL;
    }

    int t=1;cin>>t;
    while(t--){
        solve();
    }

    return 0;
}

标签:60050,状态,HDU,管控,int,多校,long,bi,dp
From: https://blog.csdn.net/2302_81761369/article/details/140954937

相关文章

  • 2024杭电多校第6场 1002.造花(困难版)
    1002提供一种不同于正解的做法重新定义菊花图:菊花图首先是一棵树,其次存在一个点,它指向的点的度数都为1,剩下的都是度数为1的点。那么在枚举删去某个点u时,只需要:1.给u的邻点的度数-1(deg[u]--)2.维护当前度数不为1的点的个数(代码里的non1)3.维护指向的点都为1度点的点的个数(......
  • 牛客多校2024-6
    A-Cake(神金,害我调了一个半小时)Alice和Bob玩一个游戏。游戏分为2阶段。阶段1:有一棵边权值为\(0\)或\(1\)的有根树,两人轮流走,Alice先走,走到叶子就停下来。记录下经过边的权值形成一个字符串\(S\)阶段2:Bob将一个蛋糕切成\(len(S)\)块,块可以为空。然后遍历\(S\)的......
  • 2024牛客暑期多校训练营5
    目录写在前面ELBHKGJ写在最后写在前面比赛地址:https://ac.nowcoder.com/acm/contest/81600。以下按个人难度向排序。妈的坐牢场啊前期除了日常战犯环节嗯吃三发之外顺的一批,后面4h一直在J上坐牢最后样例都没过呃呃呃呃,还剩1.5hdztlb大神说会K了但是以为J能调出来没......
  • 2024杭电多校第5场
    (似乎第四场还没补)(没事,问题不大)51002Array-Gift(hdu7482)某种意义上的找规律题?若序列中存在\(a_i=gcd(a_1,a_2,...a_n)\),则显然\(a_i\)为序列中的最小值,可通过\(n-1\)次取模操作,将其他数变成\(0\),由于原序列中\(a>0\),不存在更少的操作次数。若不存在上述\(a_i\),可通......
  • 2024牛客多校6
    第五场太抽象了,失去补题欲望6ACake(A)首先假设字符串已经确定,对Oscar而言,由于一份蛋糕可以为空,在两人都尽可能取最大值的情况下,相当于忽略所有空的部分、只根据字符串的某个前缀\(s'\)划分蛋糕,按照字符串中0占比最大的前缀平均划分一定是最优的。回到游戏第一步,已知Oscar的......
  • 2024牛客暑期多校训练营5赛后补题
    2024牛客暑期多校训练营5赛后补题B.珑题意:若干2×12\times12×1的多米诺骨牌去填充......
  • 2024牛客暑期多校训练营6赛后补题
    2024牛客暑期多校训练营6赛后补题B.Cake2题意:一块正n边形的蛋糕,沿着iii和i+......
  • 2024牛客暑期多校训练营6 K.The Great Wall 2
    题意给定长为\(n\)的序列\(\{a_i\}\),分成恰好\(k\)个非空连续段使得这\(k\)的极差之和最小,对\(k=1,2,\cdots,n\)分别求解。\(n\le5000\)做法定义:令\(f_{i,j}\)为将前\(i\)个数分成\(j\)段的最小极差之和,令\(w_{l,r}\)为\(a_l,\cdots,a_r\)的极差。按\(j=1\simn\)按层转移:......
  • 2018多校集训 H. Hills And Valleys
    传送门题意给你一个\(n\leq10^5\)的序列,数字都是0-9,你可以任意翻转一个子区间,问翻转后最长不降子序列的最大长度。题解简略题解:我开始考虑的是\(f_i,j,k\)表示的是翻转\(i\)结尾的区间,翻转区间贡献了最长不降序列中\(j\)到\(k\)的部分,那么只要新加入的数小于\(j\)就可以翻......
  • 2024牛客暑期多校训练营6
    目录写在前面HBDAFI写在最后写在前面比赛地址:https://ac.nowcoder.com/acm/contest/81601#question以下按个人难度向排序。纯纯战犯场呃呃呃呃做题不看题小保底当成100抽一发我草太唐了开局吃五发呃呃呃呃中期口了三题出来写出来两道最后好歹没太烂呃呃置顶广告:中南大学A......