uva 1451(树形结合)

求y/x的最大,其实就是求斜率最大

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=100000+10;
char ss[maxn];
int sum[maxn],q[maxn];
int n,m,t;
int solve(int x1,int x2,int x3,int x4)
{
     return (sum[x2]-sum[x1])*(x4-x3)-(sum[x4]-sum[x3])*(x2-x1);
}
int main()
{
     scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
         getchar();
          scanf("%s",ss+1);
          getchar();
      sum[0]=0;
      for(int i=1;i<=n;i++)
        sum[i]=sum[i-1]+ss[i]-‘0‘;//求前缀和,也就是y
      int i=0,j=0;
      int ll=0,rr=m;
       for(int l=m;l<=n;l++)//以l结尾的点
       {
             while(i<j-1&&solve(q[j-2],q[j-1],q[j-1],l-m)>0) j--;//维护前端,使其出现凹形
             q[j++]=l-m;
             while(i<j-1&&solve(q[i],l,q[i+1],l)<=0) i++;//找到以l为结尾的凹形的切线,前面的点都不要
              int mm=solve(ll,rr,q[i],l);
              if(mm<0||m==0&&(l-q[i]<rr-ll))//如果斜率更大,则取更大的
              {
                  rr=l;
                  ll=q[i];
              }
       }
      printf("%d %d\n",ll+1,rr);
    }
    return 0;
}
时间: 2024-10-17 23:53:09

uva 1451(树形结合)的相关文章

UVa 1451 Average -斜率优化

A DNA sequence consists of four letters, A, C, G, and T. The GC-ratio of a DNA sequence is the number of Cs and Gs of the sequence divided by the length of the sequence. GC-ratio is important in gene finding because DNA sequences with relatively high

Placing Lampposts - UVa 10859 树形dp

As a part of the mission ?Beautification of Dhaka City?, the government has decided to replace all the old lampposts with new expensive ones. Since the new ones are quite expensive and the budget is not up to the requirement, the government has decid

uva 1292(树形dp)

题意:有一个树,上面有n个结点,给出每个结点有边相连的直接相邻的点,问最少选几个点能让所有的边至少有一个结点被选中. 题解:树形dp简单题,把0当做根节点. f[i][0]:不选i点,覆盖所有边的最少点 f[i][1]:选i点,覆盖所有边的最少点 状态转移方程: f[u][1] += min(f[v][1], f[v][0]);//v是u的子节点,选u点子节点可以选或不选 f[u][0] += f[v][1];//不选u点就一定要选子节点,这样保证边能覆盖 #include <stdio.h>

UVa 1407 树形背包 Caves

这道题可以和POJ 2486 树形背包DP Apple Tree比较着来做. 参考题解 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 using namespace std; 7 8 const int maxn = 500 + 10; 9 10 int n, Q; 11 vec

UVA 10859 树形DP

很明显的树形DP了,设状态dp[i][0],dp[i][1].枚举子节点放或不放的两种状态. 在此学到一种不同于一般处理的方法,题目要求被两灯照亮的边尽量多,反过来即被一灯照亮的尽量少设为e.又需要的灯尽量少设为v. 设M是一个很大的数,则M*v+e即是所求.由于M很大,所以主导作用取决于v,只要v不同M*v+e一定不会相同.当v相同,被一灯照亮的尽量少即v此时发挥作用.所以DP时只需要保存这种状态即可. #include <iostream> #include <cstdio>

uva 12223(树形dp)

题意:一个城市有n个景点,景点和景点之间的路线形成一棵无根树(也就是有n-1条边),给出景点之间的花费,一个人可以任选一个景点住在那里,然后他每年都要固定去m个景点,给出这m个景点和要去的次数,这个人每次去了景点都会回家,问他一年为了观赏景点最少花费多少钱. 题解:想了好久,看看题解才完全理解.要先把无根树转化成有根树,默认让1成为根节点,然后先dfs把每个节点v当做根节点的子树的节点数统计一下在num[v]中,因为计算u-v边的走到次数就是以v为根节点的子树的节点数的个数乘边的权值乘2(来回)

【UVA 1451】Average

题 题意 求长度为n的01串中1占总长(大于L)的比例最大的一个子串起点和终点. 分析 前缀和s[i]保存前i个数有几个1,[j+1,i] 这段区间1的比例就是(s[i]-s[j])/(i-j),于是问题转换为找斜率最大的两个点. 如图,加入j时,就要去掉b1.b2,才能维护斜率的单调递增. 以队列里的点做起点,i 结尾的线段斜率最大的是 i和队列里点组成的下凹线的切线.切点前的点就不会再用到了,因为i后面的点和他们的斜率也将不如和这个切点的斜率. 数形结合,斜率优化,单调队列. 代码 #inc

UVa 1451 (数形结合 单调栈) Average

题意: 给出一个01串,选一个长度至少为L的连续子串,使得串中数字的平均值最大. 分析: 能把这道题想到用数形结合,用斜率表示平均值,我觉得这个想法太“天马行空”了 首先预处理子串的前缀和sum,如果在坐标系中描出(i, sum[i])这些点的话. 所求的平均值就是两点间的斜率了,具体来说,在连续子串[a, b]中,有sum[b]-sum[a-1]个1,长度为b-a+1,所以平均值为(sum[b]-sum[a-1])/(b-a+1) 所以就把问题转化为:求两点横坐标之差至少为L-1,能得到的最大

UVA 1451 Average Seol 平均值

摘要:数形结合,斜率优化,单调队列. 题意:求一个长度为n的01串的子串,子串长度至少为L,平均值应该尽量大,多个满足条件取长度最短,还有多个的话,取起点最靠左. 求出前缀和S[i],令点Pi表示(i,S[i]),那么这个问题就转化成了求斜率最大的两点.画图分析可知,如果有上凸点,那么上凸点,一定不会是最优的,所以问题就变成了维护一个下凸的曲线.那么可以通过比较斜率来维护,而要求切点,在之前求出的一个切点之前的点一点不会得到更优的解. 假设在A点,即之前的切线之上,那么选切点以前的点,一定不是最