码迷,mamicode.com
首页 > 其他好文 > 详细

动态规划--Kin

时间:2018-04-23 15:48:38      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:金字塔   memset   #define   就是   amp   clu   动态   []   节点   

动态规划:

1.最大子序列和

2.LIS最长递增子序列

3.LCS最长公共子序列

4.矩阵连乘

5.数字金字塔

 

 

1.最大子序列和

#include<iostream>
using namespace std;

int maxsub(int a[],int n)       
{
	int sum=0,b=0;
	for(int i=0;i<=n;i++) 
	{
		if(b>0) b+=a[i];
  		else b=a[i];
    	if(b>sum) sum=b;
  	}
	return sum;
}

int main()
{
	int a[6]={-2,11,-4,13,-5,-2};
	cout<<maxsub(a,5)<<endl;
}

  

 

2.LIS最长递增子序列


#include<iostream>
#include<algorithm> 
#define MAX_N 1010
#define INF 10010
using namespace std;

int main()
{
	int i;
	int n;
	cin>>n;
	int a[1010];
	
	for(i=0;i<n;i++)
	{
		cin>>a[i];
	}
	int dp[MAX_N];
	fill(dp,dp+n,INF);
	for(i=0;i<n;i++)
	{
		*lower_bound(dp,dp+n,a[i])=a[i];
	}
	cout<<lower_bound(dp,dp+n,INF)-dp<<endl;
} 

  

 

 

3.LCS最长公共子序列

#include<cstring>
#include<iostream>    
#define MAXV 1000  
using namespace std; 
int dp[MAXV][MAXV];  
char s1[MAXV],s2[MAXV];  
  
bool issame(int a,int b)
{  
    return a==b?1:0;  
}  
  
int max(int a,int b,int c)
{  
    if(a>=b&&a>=c) return a;  
    if(b>=a&&b>=c) return b;  
    return c;  
}  
  
int main()
{  
    int len1,len2,i,j;    
    while(cin>>s1>>s2)
	{  
        memset(dp,0,sizeof(dp));  
        len1=strlen(s1);  
        len2=strlen(s2);  
        for(i=1;i<=len1;i++)
		{  
  			for(j=1;j<=len2;j++)
  			{  
                dp[i][j]=max(dp[i-1][j-1]+issame(s1[i-1],s2[j-1]),dp[i-1][j],dp[i][j-1]);  
            }  
        }  
		cout<<dp[len1][len2]<<endl;  
    }  
}  

  

 

4.矩阵连乘,最少的乘法次数

#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int dp[maxn][maxn],a[maxn]; 

int main()
{
    int n;
    cin>>n;
    int i,j,k,len;
    memset(dp,0,sizeof(dp)); 
    //len是设置步长,也就是j减i的值 
    for(i=0;i<n;i++) cin>>a[i];
    for(i=0;i<n-2;i++) dp[i][i+2]=a[i]*a[i+1]*a[i+2];
    //如果只有三个数就直接乘起来 
    for(len=3;len<n;len++)
    {
        for(i=0;i+len<n;i++)
        {	
			j=i+len;
            for(k=i+1;k<j;k++)
			{
				if(dp[i][j]==0) dp[i][j]=dp[i][k]+dp[k][j]+a[i]*a[k]*a[j];
			 	else dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+a[i]*a[k]*a[j]);
            }
        }
    }
    cout<<dp[0][n-1]<<endl;
}

  

 

 

5.数字金字塔

include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int triangle[110][110],dp[110][110];

int main()
{
	int N;
	cin>>N;
	memset(dp,0,sizeof(dp));
	memset(triangle,0,sizeof(triangle));
	for(int i=1;i<=N;i++)
	{
		for(int j=1;j<=i;j++)
		{
			cin>>triangle[i][j];
		}
	}
	for(int i=1;i<=N;i++)
	{
		dp[N][i]=triangle[N][i];
	}
	for(int i=N-1;i>=1;i--)
	{
		for(int j=1;j<=i;j++)
		{
			dp[i][j]=max(dp[i+1][j]+triangle[i][j],dp[i+1][j+1]+triangle[i][j]);
		}
	}
	cout<<dp[1][1]<<endl;
}

  

 树形DP

1.求解树的重心

2.求解删除树的重心后的最大子树

3.父节点和子节点不能同时选择的最大数值解

4.

 

动态规划--Kin

标签:金字塔   memset   #define   就是   amp   clu   动态   []   节点   

原文地址:https://www.cnblogs.com/masterchd/p/8918896.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!