Codeforces 360C DP 计算贡献
题意:给你一个长度为n的字符串,定义两个字符串的相关度为两个串对应的子串中第一个串字典序大于第二个串的个数。现在给你相关度,和第二个串,问满足条件的第一个串有多少个?
思路:设dp[i][j]为填了前i个字符,后面的字符和s相同,相关度为j的方案数。现在有两种转移:
1:i位置填的字符大于s[i], 那么我们假设i前面第一个与s不相等的位置是l(即s[l + 1]到s[i]是相等的), 那么相当于左端点在[l + 1, i], 右端点在[i, n]的区间都会产生贡x献,那么从dp[l][j - (n - i + 1) * (i - l)]转移过来(把后面的贡献去掉,就是dp[l][j - (n - i + 1) * (i - l)]),dp[i][j] += ('z' - s[i]) * (dp[l][j - (n - i + 1) * (i - l)]);
2:i位置填的数字小于等于s[i], 那么后面就没影响了,前面所有的l都可以转移:dp[i][j] += sum[j] * (s[i] - 'a), sum[j] 为dp[0][j]到dp[i - 1][j]的和。
代码:
#include <bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
#define db double
#define pii pair<int, int>
using namespace std;
const int maxn = 2010;
const LL mod = 1000000007;
LL dp[maxn][maxn], sum[maxn];
char s[maxn];
int main() {
int n, k;
scanf("%d%d", &n, &k);
scanf("%s", s + 1);
dp[0][0] = 1;
sum[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= k; j++) {
for (int l = i - 1; l >= 0 && j - (n - i + 1) * (i - l) >= 0; l--) {
dp[i][j] = (dp[i][j] + ((LL)('z' - s[i]) * dp[l][j - (n - i + 1) * (i - l)]) % mod) % mod;
}
dp[i][j] = (dp[i][j] + ((LL)(s[i] - 'a') * sum[j]) % mod) % mod;
sum[j] = (sum[j] + dp[i][j]) % mod;
}
}
LL ans = 0;
for (int i = 0; i <= n; i++) {
ans = (ans + dp[i][k]) % mod;
}
printf("%lld\n", ans);
}
Codeforces 360C DP 计算贡献的更多相关文章
- Codeforces1238E. Keyboard Purchase(状压dp + 计算贡献)
题目链接:传送门 思路: 题目中的m为20,而不是26,显然在疯狂暗示要用状压来做. 考虑状压字母集合.如果想要保存字母集合中的各字母的顺序,那就和经典的n!的状态的状压没什么区别了,时间复杂度为O( ...
- Codeforces 1183H DP 计算子序列数目
题意及思路:https://blog.csdn.net/mmk27_word/article/details/93999633 第一次见这种DP,有点像退背包的思想,如果发现有可能因为字母相同和前面算 ...
- Codeforces 1167F(计算贡献)
要点 容易想到排序,然后对于每个数: 人的惯性思维做法是:\(a[i]*(rank1的+rank2的+-)\).然而解法巧妙之处在于直接把所有的加和当成一个系数,然后先假装所有情况系数都是1,接着往上 ...
- Codeforces 1178F DP
题意:有一张白纸条,你需要给这张纸条染色.染色从颜色1开始染色,每次选择纸条的一段染色时,这一段的颜色必须是相同的.现在给你染色后的纸条,问有多少种染色方案? F1: 思路:最开始的想法是以染色顺序为 ...
- Codeforces 1167 F Scalar Queries 计算贡献+树状数组
题意 给一个数列\(a\),定义\(f(l,r)\)为\(b_1, b_2, \dots, b_{r - l + 1}\),\(b_i = a_{l - 1 + i}\),将\(b\)排序,\(f(l ...
- Codeforces 1167F 计算贡献
题意:给你一个函数f,计算∑(i = 1 to n)(j = i to n) f(i, j).f(i, j)的定义是:取出数组中i位置到j位置的所有元素,排好序,然后把排好序的位置 * 元素 加起来. ...
- Codeforces Round #574 (Div. 2) D1. Submarine in the Rybinsk Sea (easy edition) 【计算贡献】
一.题目 D1. Submarine in the Rybinsk Sea (easy edition) 二.分析 简单版本的话,因为给定的a的长度都是定的,那么我们就无需去考虑其他的,只用计算ai的 ...
- Codeforces 360C Levko and Strings dp
题目链接:点击打开链接 题意: 给定长度为n的字符串s,常数k 显然s的子串一共同拥有 n(n-1)/2 个 要求找到一个长度为n的字符串t,使得t相应位置的k个子串字典序>s #include ...
- Codeforces Round #574 (Div. 2) D2. Submarine in the Rybinsk Sea (hard edition) 【计算贡献】
一.题目 D2. Submarine in the Rybinsk Sea (hard edition) 二.分析 相比于简单版本,它的复杂地方在于对于不同长度,可能对每个点的贡献可能是有差异的. 但 ...
随机推荐
- ansible笔记(二)--配置文件详解
配置文件ansible.cfg约有350行语句,大多数为注释行默认配置项.该文件遵循INI格式,分为如下几类配置.(1)[defaults] [defaults] # inventory = /etc ...
- VUE中使用canvas做签名功能,兼容IE
<template> <div> <div class="msgInput"> &l ...
- Java反射学习-1 - 反射获取类的属性,方法,构造器
新建一个Person类 package cn.tx.reflect; /** * 注解初步了解 * @author Administrator * */ public class Person { p ...
- 1,MySQL常用函数
一,MySQL聚合函数 1,AVG()函数 AVG()函数是一个聚合函数,它用于计算一组值或表达式的平均值. AVG()函数的语法如下: AVG(DISTINCT expression) 例如有如下p ...
- .Net Core 使用 Swagger 提供API文档
1.运行环境 开发工具:Visual Studio 2017 JDK版本:.NET Core 2.0 项目管理工具:nuget 2.GITHUB地址 https://github.com/nbfujx ...
- Adobe Flash Player30.0.0.113离线安装包
远程控制工具 www.iis7.net/a/lm/yczmljgj/ Adobe2017年7月26日宣布,计划终结 Flash 浏览器插件,并在2020年停止开发和分发这款插件.Adobe 建议内容 ...
- 4412 Linux定时器
一.Linux定时器基础知识 1.1 定时器的使用范围 延后执行某个操作,定时查询某个状态:前提是对时间要求不高的地方 1.2 内核时间概念 Hz:(系统时钟通过CONFIG_HZ来设置,范围是100 ...
- hdu 1007 Quoit Design (经典分治 求最近点对)
Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings ...
- Python基础教程(013)--一行代码不要做多件事情
前言 学习代码编写风格 内容 语法错误报错的信息 SystaxErrot:invalid syntax 语法错误, invalid 无效 每行代码负责完成一个动作 阅读代码,从左至右,从上到下. 学习 ...
- delphi 解决RichViewEdit乱码问题
⑴ 设置RichViewEdit下面的几个属性: ① RTFReaderProperties → ParaStyleMode → rvrsAddIfNeeded ② RTFReaderProperti ...