首页 > 代码库 > 两个区间dp的题目 奇怪二叉树和卡牌游戏
两个区间dp的题目 奇怪二叉树和卡牌游戏
#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
int n,a[35],dp[35][35],root[35][35];
int num=1;
void print(int l,int r)
{
if(l>r) return;
int ro=root[l][r];
if(num++<n)
printf("%d ",ro);
else
printf("%d",ro);
print(l,ro-1);
print(ro+1,r);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
dp[i][i]=a[i];
root[i][i]=i;
}
for(int l=2;l<=n;l++)
{
for(int i=1;i+l-1<=n;i++)
{
int j=i+l-1;
for(int k=i;k<=j;k++)
{
if(k==i&&k!=j)
{
if(dp[i][j]<dp[k+1][j]+a[i])
{
dp[i][j]=dp[k+1][j]+a[i];
root[i][j]=k;
}
}
if(k==j&&k!=i)
{
if(dp[i][j]<dp[i][k-1]+a[j])
{
dp[i][j]=dp[i][k-1]+a[j];
root[i][j]=k;
}
}
if(k!=i&&k!=j&&dp[i][j]<dp[i][k-1]*dp[k+1][j]+a[k])
{
dp[i][j]=dp[i][k-1]*dp[k+1][j]+a[k];
root[i][j]=k;
}
}
}
}
printf("%d\n",dp[1][n]);
print(1,n);
return 0;
}
#include<iostream>
#include<stdio.h>
#include<memory.h>
#define MAX 0x3f3f3f3f
using namespace std;
int num[105];
int dp[105][105];
int n;
int main()
{
memset(dp,MAX,sizeof(dp));
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&num[i]);
for(int i=2; i<=n-1; i++)
{
dp[i-1][i+1]=num[i-1]*num[i]*num[i+1];
}
//dp[i][j]代表抽取i-j区间的最小值
for(int k=3; k<=n; k++)
{
for(int i=1; i+k<=n; i++)
{
int j=i+k;
//关键点:枚举最后抽取的牌
for(int e=i+1; e<=j-1; e++)
{
//最左边的牌
if(e==i+1)
dp[i][j]=min(dp[i+1][j]+num[i]*num[i+1]*num[j],dp[i][j]);
//最右边的牌
else if(e==j-1)
dp[i][j]=min(dp[i][j-1]+num[i]*num[j-1]*num[j],dp[i][j]);
//中间的牌
else
dp[i][j]=min(dp[i][e]+dp[e][j]+num[i]*num[e]*num[j],dp[i][j]);
}
}
}
printf("%d",dp[1][n]);
return 0;
}
两个区间dp的题目 奇怪二叉树和卡牌游戏
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。