E - RLE
题目大意:有一个长度为 N 的只含有小写字母字符串 S ,将S中连续相同的字母用计数法表示,如 aaa -> a3,
aaabbbcc -> a3b3c2。现在要求用计数法表示后长度严格小于原来长度的 S 数量,要求对P取模。
分析:考虑动态规划:
设 f[ i ] [ j ]为 长度为 i 的字符串 用计数法表示后长度为 j 的数量 。
sum[ i ] [ j ] 为法 f[ i ] [ j ] 前缀和。
当从最开始放字母时 可以放26种,若不是开始,要与前面的不同,只能放25种。
因为 n最多为2000 ,所以最多只有以下四种情况:
(1)放入长度为 1~9 的连续字符串 ,用计数法表示后长度为 2。
(2)放入长度为 10~99 的连续字符串 ,用计数法表示后长度为 3。
(3)放入长度为 100~999 的连续字符串 ,用计数法表示后长度为 4。
(4)放入长度为 1000~9999 的连续字符串 ,用计数法表示后长度为 5。
然后注意一下边界即可,具体转移见代码:
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cout << fixed << setprecision(7);
int n;
cin >> n >> mod;
vector<vector<modint>> f(n+1,vector<modint>(n+1,0));
vector<vector<modint>> sum(n+1,vector<modint>(n+1,0));
for(int i=1;i<=n;i++){
int k=1+to_string(i).size();
if(k<n){
f[i][k]+=26;//从头开始放
}
for(int j=2;j<n;j++){
f[i][j] += 25*(sum[max(0,i-1)][max(0,j-2)] - sum[max(0,i-10)][max(0,j-2)]);//第一种情况
f[i][j] += 25*(sum[max(0,i-10)][max(0,j-3)] - sum[max(0,i-100)][max(0,j-3)]);//第二种情况
f[i][j] += 25*(sum[max(0,i-100)][max(0,j-4)] - sum[max(0,i-1000)][max(0,j-4)]);//第三种情况
f[i][j] += 25*(sum[max(0,i-1000)][max(0,j-5)] - sum[max(0,i-10000)][max(0,j-5)]);//第四种情况
sum[i][j] = sum[i-1][j] + f[i][j];
}
}
modint ans;
for(int i=1;i<n;i++){
ans+=f[n][i];
}
cout << ans.val();
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
F - Ignore Operations
题目大意:最初 x 为 0 ,有 N 个操作 ,操作有2种类型:
(1) y 替换 x
(2) x 加上y
你可以跳过最多k次操作,求操作完后最大的 x。
分析:考虑贪心。
假如后面有操作1不跳过,前面的操作不用跳了(没必要),所以当考虑某个操作1不跳时,后面的操作1必须全跳。
我们从后往前枚举第i的操作1不跳,把后面操作2为负数的用一个大根堆维护(正数直接加就好了),大小为 k - (已经跳过的操作1个数),然后更新最大值就可以了,具体见代码。
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cout << fixed << setprecision(7);
int n,k;
cin >> n >> k;
vector<pii> a(n+1);
for(int i=1;i<=n;i++) cin >> a[i].fi >> a[i].se;
a[0] = {1,0};
priority_queue<int> pq;
LL sum=0,psum=0,ans=-1e18;
for(int i=n;i>=0;i--){
int op=a[i].fi,x=a[i].se;
if(op==1){
ans = max(ans,x+sum-psum);
if(k==0) break;
k--;
if(pq.size()>k){
psum-=pq.top();
pq.pop();
}
}else{
if(x<0){
if(pq.size()<k){
psum+=x;
pq.push(x);
}else if(pq.size()&&pq.top()>x){
psum-=pq.top();
pq.pop();
pq.push(x);
psum+=x;
}
}
sum+=x;
}
}
cout << ans << '\n';
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48