T3 思路

依次枚举每个同学是否可能是凶手。最终结果有三种:

可能的凶手只有一个,输出凶手名字;

可能的凶手多于一个,输出"Cannot Determine"

任何一个同学都不可能是凶手,输出"Impossible"

在枚举每个同学是凶手的过程中,依次枚举今天是星期几,然后判断说谎的同学是否有可能有n个。

注意:

每个同学需要始终如一,如果出现某个同学既说真话又说假话,那么当前枚举的情况不合法; 每个句子有三种情况:真话、假话、废话。 最终只要假话数量 ≤n≤ 假话数量 + 废话数量,那么说谎的同学就有可能有n个;

T4 思路

首先将环从起点处断开,然后复制一遍接在后面,这样原问题就转化成了线段型的模型。【破环成链】 然后从集合角度来分析状态表示和状态计算:

状态表示:

f[l][r][i],表示所有将a[l...r]分割成i部分的方案的最大乘积; g[l][r][i],表示所有将a[l...r]分割成i部分的方案的最小乘积;

状态计算:

如果最后一段是a[k...r],那么这一类的最大值是 f[l][k - 1][i - 1] * sum(a[k...r]),其中sum()计算某一段数的和模10的余数。

f[l][r][i]取所有类别的最大值即可。

g[l][r][i]取所有类别的最小值即可。

最终枚举所有长度是n的区间,取最大值/最小值即可。

for (int len = 1; len <= n; len++) // 枚举区间长度
{
	for 枚举起点l:
	{
		计算终点r = l+len-1;
		初始化当前区间 [l,r] 分为一段的情况 f[l][r][1];
		for (枚举所有分段) // 从2开始
		{
			for (枚举分段的断点)
				状态转移
		}
	}
}

1 条评论

  • @ 2024-8-5 16:48:35
    10 10 10
    A
    B
    C
    D
    E
    F
    G
    H
    I
    J
    A: B is guilty.
    B: C is guilty.
    C: D is guilty.
    D: E is guilty.
    E: F is guilty.
    F: G is guilty.
    G: H is guilty.
    H: I love you!
    I: I am not guilty.
    J: I is not guilty.
    
    I
    
    • 1