我们定义dp[ i ]表示长度为 i 的序列, 最后没有一个==k的时候返回的方案数, 也就是最后强制返回 i 的方案数. 我们能得到dp方程   dp[ i ] = sum(dp[ i - j - 1 ] * comb(i - 1,  j) * F[ j ])  0 <= j <= k - 1, 然后会发现这个东西不好转移, 我们可以把comb(i - 1,  j) * F[ j ] 这个东西合并一下变成 F(i - 1) / F(i - 1 - j) 然后就变成   dp[ i ] = F…
题目链接  Maximum Element 题意  现在有这一段求序列中最大值的程度片段: (假定序列是一个1-n的排列) int fast_max(int n, int a[]) { int ans = 0; int offset = 0; for (int i = 0; i < n; ++i) if (ans < a[i]) { ans = a[i]; offset = 0; } else { offset = offset + 1; if (offset == k) return ans…
DP的学习计划,刷 https://codeforces.com/problemset?order=BY_RATING_ASC&tags=dp 遇到了这道题 https://codeforces.com/problemset/problem/702/A 以为是最长上升子序列(Longest Increasomg Subsequence)的模板题,发现自己不会做 记录一下大概的思路: \(O(n^2)\) 的算法: \(L[i]\) 选择 \(A[i]\) 为结尾的LIS的长度 \(P[i]\)…
<题目链接> 题目大意:给出一个01矩阵,行与行之间可以互换位置,问能够得到最大的全1矩阵的面积. #include <bits/stdc++.h> using namespace std; ; int n,m; int dp[N][N]; char mpa[N][N]; int main(){ while(~scanf("%d%d",&n,&m)){ ;i<=n;i++)scanf(); memset(dp,,sizeof(dp)); ;…
题目链接:http://codeforces.com/problemset/problem/332/B 题目大意:给你n个数和一个整数k,要求找到不相交的两个长度为k的区间,使得区间和最大,输出这两个区间的起点.解题思路:先计算前缀和,然后预处理出maxsum[i],maxsum[i]记录i~n最大的长度为k子段的和.然后再去枚举即可. #include<cstdio> #include<iostream> #include<algorithm> #include<…
https://codeforc.es/gym/102222/problem/F 注意到其实用unsigned long long不会溢出. #include<bits/stdc++.h> using namespace std; typedef long long ll; inline int read() { int x=0; int f=0; char c; do { c=getchar(); if(c=='-') f=1; } while(c<'0'||c>'9'); do…
[CF886E]Maximum Element 题意:小P有一个1-n的序列,他想找到整个序列中最大值的出现位置,但是他觉得O(n)扫一遍太慢了,所以它采用了如下方法: 1.逐个遍历每个元素,如果这个元素比当前记录的最大值大,则令最大值等于当前元素,并令cnt=02.如果这个元素没有当前元素大,则cnt++.3.如果cnt=k,则返回当前最大值 现在小P想知道有多少种序列在使用他的方法时会得到错误的答案.为了简化问题,我们假定原序列是一个1-n的排列.即我们要求的是:给定n和k,有多少个1-n的…
[题目]C. Maximum Element [题意]给定n和k,定义一个排列是好的当且仅当存在一个位置i,满足对于所有的j=[1,i-1]&&[i+1,i+k]有a[i]>a[j],求长度为n的好的排列数.n<=10^6. [算法]排列组合+动态规划 [题解]设D(n)表示长度为n且满足a[n]=n的好的排列数,考虑这样的一个排列w. 如果数字n-1的位置j<n-k,那么显然这是一个好的排列. 如果数字n-1的位置j>=n-k,那么位置j前的数字一定<n-1…
题目链接:Codeforces 484B Maximum Value 题目大意:给定一个序列,找到连个数ai和aj,ai%aj尽量大,而且ai≥aj 解题思路:类似于素数筛选法的方式,每次枚举aj,然后枚举k,每次用二分找到小于k∗aj而且最大的ai,维护答案,过程中加了一些剪枝. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn =…
题目描述 给你一个长度为 $n$ 的序列 $\{a_i\}$ 和一个数 $x$ ,对于任意一个 $1\sim n$ 的排列 $\{p_i\}$ ,从 $1$ 到 $n$ 依次执行 $x=x\ \text{mod}\ a_{p_i}$ ,最终得到一个数.求所有排列中能够得到的这个数的最大值,以及有多少种排列可以得到这个值. $n\le 1000$ ,$x\le 5000$ . 题解 组合数学+dp 由于 $a\ \text{mod}\ b<b$ ,因此每次产生影响(即 $x\ \text{mod}…