#include
#include
#include
#include
#include
#include
#define F(i,a,b) for(int i=a;i<=b;i++)
#define FD(i,b,a) for (int i=b;i>=a;i--)
#define ll long long
#define db double
using namespace std;
A:
给L,R 要求两个数ans1、ans2,使得L <=ans1、ans2、LCM(ans1,ans2) <=R (ans1 != ans2)
(不妨认定ans1
所以我们要让LCM尽量小,那么GCD就要尽量大
GCD最大是ans1
此时LCM为ans2
为了让此时的ans1小一些 ans1就取L 而为了让ans2小一些 ans2只能取2*ans1
int T;
cin >> T;
while (T--) {
ll L, R; ll ans1, ans2;
cin >> L >> R;
if (L * 2 > R) {
cout << "-1 -1\n";
}
else {
cout << L << ' ' << L * 2 << endl;
}
}
B:
从a1 开始 (ans 初始为 a1) 进行k次如下操作中的一种:
注意到数据中限制了往回走的次数不多于5次 而且数组长度也不过1w 是个很显然的动规框架
因为操作2不允许连续做的限制,所以状态的表示要多一维表示是否能够往回走
用 f[i][j][k] 表示: 取到 i 处,用了 j 次返回 ,k = 0 表示可以从此处返回 k = 1 表示不可以
转移方程2行即可:
f[i][j][0] = max(f[i - 1][j][0] + a[i], f[i - 1][j][1] + a[i]);
// 可以往回走 只能取到前面一格时往后走一格
f[i][j][1] = f[i + 1][j - 1][0] + a[i];
// 不可以往回走 只能是从后面一格的可以往回走的状态下转移过来
int main()
{
int T;
cin >> T;
while (T--) {
int n, k, z;
cin >> n >> k >> z;
F(i, 1, n+1) {
F(j, 1, z) {
f[i][j][0] = 0;
f[i][j][1] = 0;
}
}//预处理
F(i, 1, n) {
scanf("%lld", a+i);
}
//DP主体
F(i, 1, n) f[i][0][0] = f[i - 1][0][0] + a[i];
F(j, 1, z) {
F(i, 1, n) {
f[i][j][0] = max(f[i - 1][j][0] + a[i], f[i - 1][j][1] + a[i]);
f[i][j][1] = f[i + 1][j - 1][0] + a[i];
}
}
ll ans = f[k+1][0][0]; //最后从可能答案中取的时候 也有一些注意点
F(i, 1, z) {
if (k + 1 - (2 * i) > 0) {
if (f[k + 1 - (2 * i)][i][0] > ans) ans = f[k + 1 - (2 * i)][i][0];
if (f[k + 1 - (2 * i)][i][1] > ans) ans = f[k + 1 - (2 * i)][i][1];
}
}
cout << ans << endl;
}
return 0;
}
C:
对于一个字符串S 如果:
将它的首位移动到末尾得到的S1
将它的末位移动到首位前得到的S2
S1==S2 那么说明这个串S是好串
现在问给一个串去掉最少的字符使之变成好串 输出去除数
首先要分析得到,当一个串是好串的时候 具有一种传递性
使得要有1 3 5 7…位都是一样的0 2 4 6…位都是一样的
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200731213731458.png
(如图 先看后两行的传递 他们实际代表的位置在第一行)
所以最后的好串只有2个以下的不同数字构成
所以暴力枚举这两个数字字符是哪两个,然后在原串中找符合这两个字符一个隔着一个的排列的非连续子串 最后比较的最大
有个小坑点,如果两个数字字符不一样 那么最后的答案一定是偶数 是奇数的话-1
而如果字符一样 那么最后答案就不需要管奇偶性
char s[200020] = {};
int mp[10] = {};
int main()
{
int T;
cin >> T;
while (T--) {
memset(s, 0, sizeof(s));
scanf("%s", s + 1);
int len = strlen(s+1);
memset(mp, 0, sizeof(mp));
int ans = 0;
F(i, 0, 9) {
F(j, 0, 9) { //爆搜这俩字符
int len2 = 0;
int preIsI = 0;
int sta = 0;
F(k, 1, len) { //看哪一个字符先出现
if (s[k] == '0' + i) {
len2++;
preIsI = 1;
sta = k + 1;
break;
}
if (s[k] == '0' + j) {
len2++;
preIsI = 0;
sta = k + 1;
break;
}
}
F(k, sta, len) { //找一个隔着一个的最长非连续串
if (s[k] == i + '0' && !preIsI) {
preIsI = 1;
len2++;
}
else if (s[k] == j + '0' && preIsI) {
preIsI = 0;
len2++;
}
}
if (i != j) { //小坑点
if (len2 % 2 == 1) {
len2--;
}
}
if (len2 > ans) {
ans = len2;
}
}
}
cout << len-ans << endl;
}
return 0;
}