hdu 5900 区间dp
2024-09-01 12:39:14
题意:给你n对pair 里面有两个值,分别是key 和 val 。你可以取相邻的两个pair 获得其中的val,前提是两个pair 的key 的 gcd 不为 1。当然你把相邻的两个取走了之后原本不相邻的两个就变得相邻了。比如:你将下标为 2,3 取走之后,下标1,4就变得相邻了,求你可以获得的最大val。
题解:典型的合并问题,应该能想到用区间dp,但这里得考虑清楚,状态怎么转移。我们定义dp[i][j]为i~j能够获取的最大值。那么怎么更新状态呢,我们用一个前缀和去维护val,如果
dp[i+1][j-1]能够取完,其值一定为sum[j-1]-sum[i]。如果当前的区间i,j互质,那么i~j都可以取完。否则我们就要考虑剩下哪些val能够使最终的结果最大,这里就用for循环去跑一遍,枚举中间值k,看剩下哪些值是最优解。
(对区间dp的构造有了更深的理解 过几天可以写一篇小结了)。
ac代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#define mt(a) memset(a,0,sizeof(a))
using namespace std;
typedef long long ll;
ll key[];
ll v[];
ll dp[][];
ll sum[];
ll gcd(ll a,ll b)
{
if(b==) return a;
return gcd(b,a%b);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
mt(dp);
mt(sum);
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%lld",&key[i]);
}
for(int i=;i<=n;i++)
{
scanf("%lld",&v[i]);
sum[i]=sum[i-]+v[i];
}
for(int l=;l<=n;l++)
{
for(int i=;i+l-<=n;i++)
{
int j=i+l-;
if(dp[i+][j-]==(sum[j-]-sum[i]) && gcd(key[i],key[j])!=)
{
dp[i][j]=sum[j]-sum[i-];
continue;
}
for(int k=i;k<j;k++) dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+][j]);
}
}
//
printf("%lld\n",dp[][n]);
}
}
最新文章
- FragmentTabHost的基本用法
- jQuery和AngularJS的区别小分析
- JsonProperties对模型返回的应用
- POJ2195 Going Home
- 高性能Mysql
- Stanford大学机器学习公开课(五):生成学习算法、高斯判别、朴素贝叶斯
- pyqt tabWidget例子学习1
- Qt 多线程与数据库操作需要注意的几点问题
- PAT1093: Count PAT&#39;s
- Oracle篇 之 数据操作
- Linux虚拟机安装及环境搭建
- Spring Boot 多模块项目创建与配置 (一) (转)
- linux链接库的理解
- P1858 多人背包
- 成功让Eclipse更新ADT的方法
- 反转ListBox的ListBoxItem(控件级别,不是数据的反转)
- What is the difference between J2EE and Spring
- Linux内核优化(未注释)
- Java学习之路(六):集合
- 简述JavaScript的类与对象
热门文章
- springmvc配置mybatis与hibernate的不同点
- redis安装与介绍
- 多网卡下如何配置指定IP走某个路由器(适用于外网不通,但是钉钉服务器通的情况)
- SVG-概述/容器与通用属性
- 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_13-SpringSecurityOauth2研究-JWT研究-生成JWT令牌&;验证JWT令牌
- (十)会话跟踪技术之Session
- pcntl_waitpid函数解释
- 第十三章 RememberMe——《跟我学Shiro》
- 使用javamelody监控springboot项目
- git merge仓