首页 > 其他分享 >[HNOI2008] 玩具装箱 题解

[HNOI2008] 玩具装箱 题解

时间:2023-07-07 20:22:23浏览次数:41  
标签:node 50005 int 题解 sum yy xx HNOI2008 装箱

很难得遇到细节题
打码5分钟调试两小时
感谢游老师送出的1.5h调试,感激
(争取每天用我的代码训练老师的该题能力)
细节/思路见注释

#include <bits/stdc++.h>
#define int long long
using namespace std;
/*
本题细节很多!!!

1.注意要把‘0’放进去,否则'1'一直弹不出去,导致答案偏大
2.放了'0‘以后,注意初始化,例如h[0]=L+1;同理,’0‘在坐标轴上也是,如g[0]
3.我这个代码有点绕,有用数组,也有用函数值,注意这两个都要赋值
最后感谢游老师1h送出的调试AC 

f[i]=min_j(f[j]+(i-j-1+sum[i]-sum[j]-L)^2)
i和j提出来给函数
g[i]=sumi+i;
h[i]=i+sum[i]+L+1

再拆开:=min_j(f[j]+(g[i]-h[j])^2)=min_j(g[i]*g[i]+h[j]*h[j]+f[j]-2*g[i]*h[j])
斜率优化公式中
a[i]=-2*g[i],b[j]=h[j],c[i]=g[i]*g[i],d[j]=h[j]*h[j]+f[j]
坐标(bj,-dj)
fi=ci- b,b是我线性规划要求的
显然横坐标递增(bi)
k则是递减(ai)


*/
int sum[50005];
int g[50005], h[50005], cost[50005];
int k[50005];
int a[50005], b[50005], c[50005], d[50005];
int dp[50005];

struct node {
    int xx;
    int yy;
    int id;
};
node Q[400005];
bool check(node x, node y, int z) {  //队首,次级队首,末尾,肯定是整数
    double k1 = 1.0 * (y.yy - x.yy) / (y.xx - x.xx);
    //cout<<x.id<<' '<<y.id<<' ' <<k1<<' '<<z<<endl;
    if (k1 >= z) {  //前者偏大
        return 1;
    } else {
        return 0;
    }
}
bool checkdot(node x, node y, node z) {  //队首,次级队首,末尾,肯定是整数
    double k1 = 1.0 * (y.yy - x.yy) / (y.xx - x.xx);
    double k2 = 1.0 * (z.yy - y.yy) / (z.xx - y.xx);
    if (k1 > k2) {  //前者偏大 ,成立
        return 1;
    } else {
        return 0;
    }
}
deque<node> q;
signed main() {
    //ios::sync_with_stdio(false);
    int n, L;
    cin >> n >> L;
    for (int i = 1; i <= n; i++) {
        cin >> cost[i];
        sum[i] = sum[i - 1] + cost[i];
    }
    h[0]=L+1;
    for (int i = 1; i <= n; i++) {
        g[i] = i + sum[i];
        h[i] = i + sum[i] + L + 1;

        a[i] = 2 * g[i] * (-1);

        c[i] = g[i] * g[i];
        //
        //		b[i]=h[i];
        //		d[i]=h[i]*h[i];
    }
    int head = 1;
    int tail = 1;
    //dp[1] = (cost[1] - L) * (cost[1] - L);
    Q[head] = (node){ L+1, -(L+1)*(L+1), 0 };
    for (int i = 1; i <= n; i++) {
        while (head < tail && check(Q[head], Q[head + 1], a[i])) {
            ++head;
        }
        int j = Q[head].id;
        dp[i] = (a[i] * h[j] + c[i] + h[j] * h[j] + dp[j]);
        //cout<<j<<endl;
        node now = (node){ h[i], -(h[i] * h[i] + dp[i]), i };
        while (head < tail && checkdot(Q[tail - 1], Q[tail], now) == 0) --tail;
        Q[++tail] = now;
        /*if(i<=10) {
        	for(int jj=head;jj<=tail;++jj)
				cout<<Q[jj].xx<<' '<<Q[jj].yy<<' '<<Q[jj].id<<endl;
			//cout<<dp[1]<<' '<<h[1]<<endl;
			//cout<<endl;
			
		}*/
    }
    cout << dp[n] << endl;
}

标签:node,50005,int,题解,sum,yy,xx,HNOI2008,装箱
From: https://www.cnblogs.com/linghusama/p/17535970.html

相关文章

  • 题解 P8648【[蓝桥杯 2017 省 A] 油漆面积】
    怎么题解区全是扫描线,还有个\(O(n^3)\)暴力老哥。为防止误导新人,给个理论上稳过的\(O(n^2)\)解法。二维前缀和可以处理若干次单点加,最后若干次矩形查的问题。将其差分,即可处理若干次矩形加,最后若干次单点查的问题。于是我们使用差分将所有矩形加上,然后做一遍二维前缀和,即......
  • 「NOIP 模拟赛 20230707」T2 - 涂照片 题解
    题目大意原题有一个\(n+1\timesm+1\)的网格。对于每一行\(i\),都要将左侧的一些格子\((i,1),(i,2),\ldots,(i,x)\)涂黑,其中\(x=k\)的概率为\(a_{i,k}\)。同理对于每一列\(j\),都要将上方的一些格子\((1,j),(2,j),\ldots,(x,j)\)涂黑,其中\(x=k\)的概率为\(b_{k,......
  • P7561[JOISC 2021 Day2] 道路の建設案 (Road Construction) 题解
    P7561[JOISC2021Day2]道路の建設案(RoadConstruction)题解题目描述JOI国是一个\(x\timesy\)的二维平面,王国里有\(n\)个城镇,分别编号为\(1,2,\cdots,n\in[1,2.5\times10^5]\),其中第\(i\)个城镇的坐标为\((x_i,y_i)\)。在JOI国,正计划修建连接两座城......
  • AT_bcu30_2019_qual_a 题解
    思路纯模拟题,给定N和P后,定义一个计数器sum,重复N次输入,每输入一次就判断P也就是子弹的能量是否≥每面墙的厚度x,如果是,就用P减去x,sum增加1,表示穿过了一面墙,否则跳出循环,输出sum。代码#include<iostream>usingnamespacestd;intmain(){intn,p,sum=0,......
  • AT_nikkei2019ex_h 题解
    思路这是一道博弈题,最优策略是高桥的k一直是1,青木的k一直是0,可以保证拿走的硬币不超过剩下的硬币,这样每次两人都取完后拿走硬币的数量是8^1+8^0,结果是9,那么就用Nmod9,得出的结果就是剩下的硬币。如果结果是0,那么最后拿的就是青木,输出Lose。如果结果是2、4、6,都......
  • 【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(三)
    ​贴接上回。。。 【往期FAQ参考】【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(一)【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(二) 【本期FAQ】1、第一次调用geolocation.getCurrentLocation()接口,弹出权限弹框后并未返回结果,再次调用接口才会成功返回?(API8......
  • AT_nikkei2019ex_e 题解
    思路进题扫一眼题目描述,可以写成这样:是不是很眼熟?这不就是角谷猜想嘛,但它不是让我们求步数果,而是求结果。它给了步数,求结果那就要倒推,第二个样例给了P最大时,也就是1000输出的结果1789997546303,我们就用这个结果往前推,带入角谷猜想的运算过程,就可以了。记得开longlong。......
  • AT_pakencamp_2020_day1_c 题解
    思路看到题目的第一句话我就知道要用map了。一道map的入门题,定义一个map来输入和统计参加次数后,定义一个计数器sum用来统计人数。代码#include<iostream>#include<string>#include<map>usingnamespacestd;map<string,int>personnel;intmain(){intn,sum......
  • CF1451F 题解
    problem&blog。这题原本的题解满是废话,让我写一篇(这边直接给结论了。令\(val_p=\oplus_{x+y=p}\a_{x,y}\),设\(S=\Big[\normalsize\forallval_i=0\Big]\),当\(S=\text{true}\)时,后手必胜;否则先手必胜。证明也是典中典。证两个条件即可。证明\(\forallS\Rightarr......
  • 记一次重装windows系统后笔记本键盘不能用的问题解决
    刚买了一台笔记本,预装的是Windows11。这个系统我见识过,优点还没看到,不习惯的地方很多。所以重装了Windows10LTSC。结果装完笔记本键盘不能用。这个情况之前用拯救者Y7000装plex的时候也遇到过,那时候没解决,这次非处理好不可下载驱动管理软件看,没有显示有对应键盘的驱动进设备管......