1.前缀和
前缀和就是将一个区间内的数总和在一起,比如
for (int i = 1; i <= n; i ++ )
{
cin >> a[i];
s[i] = s[i - 1] + a[i];
}
前缀和就是从位置1到位置i这个区间内的所有的数字之和。
前缀和的优势:以(o1)的时间复杂度得到某块区间的总和。
复杂度低,计算方便,在输入的过程中就能计数。
我们可以灵活的运用前缀和:
如规定i=0;j=0,然后再i循环中定义一个单次的j操作,两重循环一重循环输入,一重计算和。
2.差分
差分就是将数列中的每一项分别与前一项数做差。
需要注意的地方是差分的时候,差分后的数组和差分前的数组的第一个数是相同的,相当于第一个数与0做差。
3.LCS
LCS问题就是求两个序列的重合序列,但是要按照顺序来且不用连续进行。
最具LCS特点的动态规划问题:
**B **
#include <stdio.h>
#include <string.h>
#include <map>
#include <algorithm>
using namespace std;
#define MAX(x,y)(x>y?x:y)
const int MAXN=2100;
int dp[2][MAXN];
char a[MAXN],b[MAXN],c[MAXN];
map<char,int>mp;//用map记录数组
int main()
{
int N,temp;
while(~scanf("%d",&N))//读到文本文件末尾为止
{
memset(dp,0,sizeof(dp));
mp.clear();
scanf("%s",a+1);
for(int i=1; i<=N; i++)
{
scanf("%d",&temp);
mp[a[i]]=temp;
}
scanf("%s",b+1);
scanf("%s",c+1);
int t1,t2;
t1=strlen(b+1);
t2=strlen(c+1);
for(int i=1; i<=t1; i++)
for(int j=1; j<=t2; j++)
if(b[i]==c[j])
dp[i&1][j]=dp[(i-1)&1][j-1]+mp[b[i]];
else
{
int k=MAX(dp[(i-1)&1][j],dp[i&1][j-1]);
dp[i&1][j]=MAX(k,dp[(i-1)&1][j-1]);
}
printf("%d\n",dp[t1&1][t2]);
}
return 0;
}
此题目就是经典的lcs题目,这个题目的关键点就是在状态转移方程上
动态规划对于目前的我来说是十分的难的,再者就是时间有点抽不出来,一堆事情堆积,然后目前来说,可能需要来用熬夜或者一些其他的时间来增加学习的时间。
动态规划的本质就是子问题的确定和转移,找到子问题,用子问题的答案来引到下一个子问题答案的出现是动态规划题目的重点,所以下一步我需要加强对动态规划的读题水平。