1.数字三角形
动规第一道例题,很具有代表性。
动态规划解题思路:
① 将原问题分解成子问题
② 确定状态
③ 确定初始状态的值,即递推自下而上的最底层初值
④ 确定状态转移方程
2.最长上升子序列
两种动规方法 “我为人人”型 和 “人人为我”型
自己感觉“人人为我”在大部分题目中比较容易想到
//人人为我
for (int i = 2; i <= N; ++i)
for (int j = 1; j < i; ++j)
if (a[i] > a[j])
maxLen[i] = max(maxLen[i], maxLen[i] + 1);
//我为人人
for (int i = 1; i < N; ++i)
for (int j = i + 1; j <= N; ++j)
if (a[j] > a[i])
maxLen[j] = max(maxLen[j], maxlen[i] + 1);
3.最大上升子序列和
题目链接: http://cxsjsx.openjudge.cn/2015finalpractice/30/
例题练习,稍微有改动, 就犯了些错误/(ㄒoㄒ)/~~
int main()
{
int N;
int maxLen[1001];
int a[1001];
while (scanf("%d", &N) != EOF)
{
for (int i = 0; i < N; ++i)
{
scanf("%d", &a[i]);
}
maxLen[0] = a[0];
for (int i = 1; i < N; ++i)
{
maxLen[i] = a[i];//注意这里!一定要用a[i]初始化,否则可能会赋不上值
//比如序列{102, 100, 101}
for (int j = 0; j < i; ++j)
{
if (a[i] > a[j])
//与最长上升子序列类似的状态转移方程
maxLen[i] = max(maxLen[i], maxLen[j] + a[i]);
}
}
int cmax = 0;
for (int i = 0; i < N; ++i)
{
if (cmax < maxLen[i])
cmax = maxLen[i];
}
printf("%d\n", cmax);
}
return 0;
}
4.最长公共子序列
给出两个字符串,求出这样的一个最长的公共子序列的长度:子序列中的每个字符都能在两个原串中找到,而且每个字符的先后顺序和原串中的先后顺序一致。
状态:MaxLen[i][j] :s1左边i个字符形成的子串和s2左边j个字符形成的子串的最长子序列长度。
//状态初始化
for( i = 0;i <= length1; i ++ )
maxLen[i][0] = 0;
for( j = 0;j <= length2; j ++ )
maxLen[0][j] = 0;
for( i = 1;i <= length1;i ++ )
{
for( j = 1; j <= length2; j ++ )
{
//核心,状态转移方程,很有趣
if( sz1[i-1] == sz2[j-1] )
maxLen[i][j] = maxLen[i-1][j-1] + 1;
else
maxLen[i][j] = max(maxLen[i][j-1],maxLen[i-1][j]);
}
}
5. UNIMODAL PALINDROMIC DECOMPOSITIONS
题目链接:http://cxsjsx.openjudge.cn/hw201614gw/A/
心得:很难想到...看了网上的代码才勉强理解,不过已知答案再回头分析也能够通过动规的思路来解释,看来还是要多积累经验
#define N 300
int main()
{
int i, j;
int n;
long long s[N][N];
memset(s, 0, sizeof(s));
//状态:s[i][j]i是待分解元素,表示i中元素大于等于j的序列个数,不太容易想到
for (j = 1; j < N; j++)
s[0][j] = 1;//i被拆成两个相同的数
for (i = 1; i < N; i++)
for (j = i / 2 + 1; j <= i; j++)
s[i][j] = 1;// j > i/2时只有一种情况就是i本身
for (i = 2; i < N; i++)
for (j = i / 2; j > 0; j--)
s[i][j] = s[i - 2 * j][j] + s[i][j + 1];//状态转移方程
while (scanf("%d", &n) && n)
{
printf("%d %lld\n", n, s[n][1]);//**oj的处理器似乎不能用I64**
}
return 0;
}