题目链接

题意分析

首先 我们肯定会贪心的走从根节点到叶子结点最长的一条链

首先没有过剩的就好办了

但是有的话 我们就一边往下走 一边走分支

分支上每一个点平均走过两次

所以我们把剩下的除以\(2\)即可

CODE:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<list>
#include<set>
#include<deque>
#include<vector>
#include<ctime>
#define ll long long
#define inf 0x7fffffff
#define N 500008
#define IL inline
#define M 1008611
#define D double
#define ull unsigned long long
#define R register
using namespace std;
template<typename T>IL void read(T &_)
{
T __=0,___=1;char ____=getchar();
while(!isdigit(____)) {if(____=='-') ___=0;____=getchar();}
while(isdigit(____)) {__=(__<<1)+(__<<3)+____-'0';____=getchar();}
_=___ ? __:-__;
}
/*-------------OI使我快乐-------------*/
struct Node{
int le,ri,d;
}e[M];
int n,m,tot;
int res[M],ans[M],cnt[N][M];
int dp[N][N][M],pre[N][N][M],pos[N][N][M];
IL void getans(int le,int ri,int at)
{
if(le>ri) return;
int now=pos[le][ri][at=pre[le][ri][at]];
ans[now]=res[at];
getans(le,now-1,at);getans(now+1,ri,at);
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
read(n);read(m);
for(R int i=1;i<=m;++i) read(e[i].le),read(e[i].ri),read(e[i].d),res[i]=e[i].d;
sort(res+1,res+m+1);tot=unique(res+1,res+m+1)-res-1;
for(R int i=1;i<=m;++i) e[i].d=lower_bound(res+1,res+tot+1,e[i].d)-res;
// for(R int i=1;i<=m;++i) printf("%d%c",e[i].d,(i==m ? '\n':' '));
for(R int i=n;i;--i)
{
for(R int j=i;j<=n;++j)
{
for(R int k=i;k<=j;++k)
for(R int lim=0;lim<=tot;++lim)
cnt[k][lim]=0;
for(R int k=1;k<=m;++k)
if(i<=e[k].le&&e[k].ri<=j)
for(R int l=e[k].le;l<=e[k].ri;++l)
cnt[l][e[k].d]++;
for(R int k=i;k<=j;++k)
for(R int l=tot-1;l;--l)
cnt[k][l]+=cnt[k][l+1];
for(R int k=tot;k;--k)
{
int maxn=0;
for(R int l=i;l<=j;++l)
{
int wson=dp[i][l-1][k]+dp[l+1][j][k]+cnt[l][k]*res[k];
if(maxn<=wson) maxn=wson,pos[i][j][k]=l;
}
if(maxn>=dp[i][j][k+1]) dp[i][j][k]=maxn,pre[i][j][k]=k;
else dp[i][j][k]=dp[i][j][k+1],pre[i][j][k]=pre[i][j][k+1];
}
}
}
getans(1,n,1);
printf("%d\n",dp[1][n][1]);
for(R int i=1;i<=n;++i) printf("%d%c",ans[i],(i==n ? '\n':' '));
// fclose(stdin);
// fclose(stdout);
return 0;
}

HEOI 2019 RP++

最新文章

  1. RabbitMq 集群搭建
  2. 关于安卓APP的启动界面
  3. 微信小程序-基础内容组件
  4. 【转】WordPress转PHPCMS策略-数据库完美转换
  5. 新著作计划:《水利水电工程施工导流 水力计算与.NET编程》
  6. ACM题目————数素数
  7. iOS 对网络视频采集视频截图
  8. MySQL Explain 结果解读与实践
  9. 命令行工具命令 - run包到手机里
  10. 从源代码角度分析ViewStub 疑问与原理
  11. Beta预备会议
  12. python爬虫 - python requests网络请求简洁之道
  13. Java集合类源码解析:AbstractList
  14. 高斯消元(Gauss消元)
  15. 【BZOJ1011】【HNOI2008】遥远的行星 误差分析
  16. 【hdu 5628】Clarke and math (Dirichlet卷积)
  17. Celery的Web监控管理--Flower
  18. Scala的Trait详解
  19. Linux安装软件包
  20. winform 控件随页面大小进行自适应

热门文章

  1. UNITY5 为什么Inspector视图中脚本前面的勾选框没了
  2. HTML 页面中的 SVG
  3. LoadRunner--Analysis各项指标详解
  4. ps 中添加一张图片
  5. ViewController的属性
  6. (转)C# .net微信开发,开发认证,关注触发消息,自动应答,事件响应,自定义菜单
  7. Git config 配置文件
  8. IntricCondition和expliciteCondition比较
  9. 无线破解那点事(PJ)
  10. polymer-developer guide-feature overview