• 【XSY3209】RGB Sequence


    题目

    传送门

    解法

    (f_{i, j, k})表示有(i)个红石块, (j)个绿宝石块, (k)个钻石块
    可以转移到(f_{p+1, j, k})(f_{i, p+1,k })(f_{i, j, p+1})(p)(max(i, j, k))

    代码

    #pragma GCC optimize(3)
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    const int mod = 1000000007;
    
    const int N = 310;
    
    const int M = 310;
    
    struct node
    {	int a, b;
    	node() { }
    	node(int _1, int _2) : a(_1), b(_2) { }
    } list[M];
    
    int head[N], nxt[M], tot;
    
    inline void init()
    {	memset(head, -1, sizeof(head));
    	tot = 0;
    }
    
    inline void link(int x, int y, int z)
    {	list[tot] = node(y, z);
    	nxt[tot] = head[x];
    	head[x] = tot++;
    }
    
    inline int max(int x, int y) { return x > y ? x : y; }
    
    inline int Plus(int a, int b) { return a + b >= mod ? a + b - mod : a + b; }
    
    int n, m;
    
    inline bool check(int a, int b, int c)
    {	int num = max(a, max(b, c));
    	for (register int i = head[num]; ~i; i = nxt[i])
    	{	int l = list[i].a;
    		int cnt = (l <= a) + (l <= b) + (l <= c);
    		if (cnt != list[i].b) return 0;
    	}
    	return 1;
    }
    
    int f[N][N][N];
    
    int Dp()
    {	f[0][0][0] = 1;
    	int Ans = 0;
    	register int i, j, k;
    	for (i = 0; i <= n; i++)
    	{	for (j = 0; j <= n; j++)
    		{	for (k = 0; k <= n; k++)
    			{	if (!f[i][j][k]) continue;
    				if (!check(i, j, k)) { f[i][j][k] = 0; continue; }
    				int p = max(i, max(j, k));
    //				if (p == n) { Ans = Plus(Ans, f[i][j][k]); continue; }
    				f[p+1][j][k] = Plus(f[p+1][j][k], f[i][j][k]);
    				f[i][p+1][k] = Plus(f[i][p+1][k], f[i][j][k]);
    				f[i][j][p+1] = Plus(f[i][j][p+1], f[i][j][k]);
    			}
    		}
    	}
    	for (int i = 0; i <= n; i++)
    		for (int j = 0; j <= n; j++)
    		{	Ans = Plus(Ans, f[i][j][n]);
    			Ans = Plus(Ans, f[i][n][j]);
    			Ans = Plus(Ans, f[n][i][j]);
    		}
    	return Ans;
    }
    
    int main()
    {	scanf("%d %d", &n, &m);
    	init();
    	for (int i = 1; i <= m; i++)
    	{	int l, r, x;
    		scanf("%d %d %d", &l, &r, &x);
    		if (r-l+1 < x) return 0 & puts("0");
    		link(r, l, x);
    	}
    	printf("%d
    ", Dp());
    	return 0;
    }
    
  • 相关阅读:
    关于程序中以时间判断接收数据结束时,接收数据长度设置为1时,出现接收不全的问题解释。
    stm32 外部8M晶振 改为12M的方法
    django iis 部署
    电信NB卡
    socketserver
    APScheduler简介
    三极管开关电路
    mysql授权
    解决VMware无法共享ubuntu虚拟机文件
    Python解析yaml配置文件
  • 原文地址:https://www.cnblogs.com/2016gdgzoi509/p/9477509.html
Copyright © 2020-2023  润新知