【动态规划】K序列

原创 2018年04月16日 16:54:44


思路

网赛的时候完全就瞎写,因为当时在想类比最大上升子序列,思路就很乱,最后写了个dfs也跑不动。果然动态规划能行,

但是由于思路限制(做dp的题做少了)也没想好。今天看的题解,豁然开朗。

两个数组:dp和temp规模都是k,因为我只需要子序列和模k的情况(结果为0~k)对应的最大长度,又是求“最值”,于是联想到动态规划。dp[j]表示算上当前的这个数值,结果为j的最大长度;temp[j]表示不算上当前的这个数值(因为最外对数组的每个元素进行遍历,相当于temp存储的是直到加到上一个元素时的情况),结果为j的最大长度。

那么显然状态转移方程为:

dp[(j+num[i])%k]=temp[j]+1;

然而还需要if语句,因为要考虑到:如果temp[j]==0就意味着之前都没有一个结果是j的,那么你dp就不应该在j的基础上去加当前这个数模k更新对应这个结果的长度,但是,j==0的时候(即一开始的时候 和 模k结果为0的情况第一次出现了)temp[j]==0,可我们需要用上。

综上,状态转移方程的条件:

if(j==0||temp[j]!=0)
至于temp数组的更新就不用说了吧,你每针对一个num数组的元素弄了一次,就该更新一次temp数组,让我知道结果为j的子序列最大长度是多少。

代码

#include<iostream>
#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5+5;
const int maxk=1e7+5;
int temp[maxk];
int dp[maxk];
int num[maxn];
int main()
{
	int n,k;
	cin>>n>>k;
	for(int i=0;i<n;i++)
		scanf("%d",&num[i]);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<k;j++)
		{
			if(j==0||temp[j]!=0)
				dp[(j+num[i])%k]=temp[j]+1;
		}
		for(int j=0;j<k;j++)
			temp[j]=max(temp[j],dp[j]);
	}
	printf("%d\n",dp[0]);
} 

感受

这道题如果让我一开始来写我是无从下手的,因为我之前太纠结于“子序列--->可以不连续--->取当前元素或不取--->dfs???”,而这个动态规划,下标表示模k的结果,数值表示长度,主要是很巧妙地针对每一个num数组的元素,在内循环通过0~k的更新(“不管你行不行我先都要”),然后通过max函数来看看要了你这个元素之后能不能把我的最大长度提高,能的话我的temp数组跟着你刷新最大长度,不能的话我temp数组还是我原来的长度(“先斩后奏,数据决定最后要不要你”)。

或许这种“不管你行不行我先都要,先斩后奏,数据决定最后要不要你”是一种动态规划求最值的思想,是我需要理解的,而不同于很直观的在dfs里立马决定我要不要你。

觉得动态规划就是这样.....每次让我遇到就要讲那么多才能让自己觉得“哦!懂了!”。之后要多做题提高才行。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38033475/article/details/79962046

激励故事[n篇]

激励故事[n篇](1)鸡与大蟒蛇   在一个动物园,饲养员每天都要喂一大盆肉给大蟒蛇吃。  这一天,饲养员突然想看看给大蟒蛇吃鸡会是什么样子。于是他就关了一只鸡到大蟒蛇的笼子里。  这只鸡突然遭遇这飞...
  • citymeteor
  • citymeteor
  • 2002-11-10 10:54:00
  • 913

最大连续子序列和:动态规划经典题目

【题目】  给定k个整数的序列{N1,N2,...,Nk },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1  【注】:为方便起见,如果所有整数均为负数,则最...
  • samjustin1
  • samjustin1
  • 2016-07-27 10:34:08
  • 2854

带k最长上升子序列

带k最长上升子序列时间限制: 1 Sec 内存限制: 128 MB题目描述LIS问题是最经典的动态规划基础问题之一。如果要求一个满足一定条件的最长上升子序列,你还能解决吗? 给出一个长度为...
  • slongle_amazing
  • slongle_amazing
  • 2015-06-25 21:42:32
  • 486

JAVA动态规划(四)--根据给定0和1的个数,求字典序排在第K位的数【微软笔试题】

题目: Time Limit: 10000ms Case Time Limit: 1000ms Memory Limit: 256MB Description Consider a stri...
  • y999666
  • y999666
  • 2016-04-22 22:00:56
  • 596

【基础练习】【二分】codevs2188 最长上升子序列(限定元素)题解

题目描述 Description LIS问题是最经典的动态规划基础问题之一。如果要求一个满足一定条件的最长上升子序列,你还能解决吗?     给出一个长度为N整数序列,请求出它的包含第K个元素...
  • ametake
  • ametake
  • 2015-10-12 19:41:38
  • 541

动态规划之合唱队形问题(最长递增子序列变形)

题目描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形。合唱队形定义:设K位同学从左到右依次编号为1, 2, …, K,他们的身高分别为T1...
  • hulifangjiayou
  • hulifangjiayou
  • 2015-08-30 20:08:02
  • 1076

用动态规划法求解生物信息学中DNA序列比对的问题 (交叉学科应用实验)

#include#include#includeusing namespace std;stack s;//当前搜索路径的LCSstack lcs[100];//所有的LCSint count=0;/...
  • zhihang1103
  • zhihang1103
  • 2013-09-26 21:37:28
  • 2180

POJ 1080 基因序列相似度计算 动态规划

本题为典型的动态规划,关键找出序列比对的3个不同情况,即子问题 设d[i][j]为取s1第i个字符,s2第j个字符时的最大分值 则决定p为最优的情况有三种 p数组为分数矩阵 1、  s1取第i个...
  • yangliuy
  • yangliuy
  • 2011-12-23 00:11:04
  • 2534

蓝桥杯 K好数(动态规划)

算法训练 K好数   时间限制:1.0s   内存限制:256.0MB 问题描述 如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数。求L位K进制...
  • u013055228
  • u013055228
  • 2014-03-02 22:58:42
  • 2879
收藏助手
不良信息举报
您举报文章:【动态规划】K序列
举报原因:
原因补充:

(最多只允许输入30个字)