正睿20NOIp前冲刺day4
估分:50+30+20=100
实际:20+80+20=120
T1:
想到的是第二种做法,只会用字典树弄发现存不下,然后RE只有20pts
一种做法:SAM板子题
另一种做法:最多可以选n个子串,就是s[1~i]的n个子串,可以发现,以s[i]结尾的所有字符串s[1~i]、s[2~i]……s[i-1~i]、s[i~i]中只能选一个,而且无论选哪一个都一样,选s[1~i]一定比其他更优,因为它最长。如果有s[1~i]是s[1~j]的后缀,那么选s[1~j]定比s[1~i]优,理由同上,所以最后就能得出结论,求一下s最长的border,答案就是所有子串数n减去重复的子串数就是border的长度,KMP求一下就行了。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int N = 1000010; 8 9 int nex[N]; 10 char str[N]; 11 12 int main() 13 { 14 scanf("%s", str + 1); 15 int j = 0, n = strlen(str + 1); 16 int ans = 0; 17 for (int i = 2; i <= n; i++) 18 { 19 while (j && str[j + 1] != str[i]) j = nex[j]; 20 if (str[j + 1] == str[i]) j++; 21 nex[i] = j; 22 ans = max(ans, nex[i]); 23 } 24 printf("%d", n - ans); 25 }
T2:
少判断了n%3==2的情况,丢了20pts
这题相当于从1~n中选一个数作为x,从1~n中选一个数为y,每个数只能选一次作为x,选一次作为y,然后要让选出来的数之和两两不同且和不大于n,问最多能选几组。我们可以画一个下面的图让他们两两匹配
两个数之间有边就表示这两个匹配为一组(x,y),经过一些打表,当x,y的范围相同且最大值是奇数时可以发现数之间能这样匹配:
所有是/的边两边都是奇数或都是偶数,所以他们的和都是互不相同的偶数且差值至少为2,所有是\的边两边一边是奇,一边是偶,所以他们的和都是互不相同的奇数且差值也至少为2,可以发现这种构造能使他们的和最大值最小。
之后看x,y范围为偶数,可以发现因为范围是偶数,按照上面的方法无论什么边两边都是一奇一偶,所以构造不出他们全部匹配且和不同的方案。为了让/和\连的数的和奇偶性不同,我们把\右边连的数往下一位,就能使奇偶性和上面相同,所以就构造成下面这样了。
最后在随便打几个表就能看出当n%3==2使用x范围为偶数的构造,其他情况用x范围为奇数的构造是最优的
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 int main() 8 { 9 int n; 10 scanf("%d", &n); 11 if (n < 3) puts("0"), exit(0); 12 int i, j; 13 int k = n / 3 * 2; 14 if (n % 3 != 2) k--; 15 printf("%d\n", k); 16 for (i = 1, j = k / 2 + 2 + (n % 3 == 2); j <= k + (n % 3 == 2); j++, i++) printf("%d %d %d\n", i, j, n - i - j); 17 for (j = 1; j <= k / 2 + 1; j++, i++) printf("%d %d %d\n", i, j, n - i - j); 18 19 }
T3:
暴力20pts没问题
玄学DP,不会
总结:
还是要回去复习一下之前学过的知识,好多都忘了。构造题还是要多看几种情况,第二题考场上最后20分钟才发现当n=8时不对,以为推错了,打完表就搞第一题去了。关于DP的题还是不行,要多练。