清北学堂模拟赛day7 石子合并加强版

/*
注意到合并三堆需要枚举两个端点,其实可以开一个数组记录合并两堆的结果,标程好像用了一个神奇的优化
*/
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define ll long long
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define fd(i,l,r) for(int i = r;i >= l;i--)
using namespace std;
const int maxn = 505;
ll read(){
    ll x=0,f=1;
    char ch=getchar();
    while(!(ch>=‘0‘&&ch<=‘9‘)){if(ch==‘-‘)f=-1;ch=getchar();};
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+(ch-‘0‘);ch=getchar();};
    return x*f;
}
int n;
ll dp[maxn][maxn],dp2[maxn][maxn],val[maxn],sum[maxn];
int main(){
    freopen("merge.in","r",stdin);
    freopen("merge.out","w",stdout);
    n = read();
    memset(dp,127/3,sizeof(dp));
    memset(dp2,127/3,sizeof(dp2));
    fo(i,1,n) val[i] = read();
    fo(i,1,n){
        dp[i][i] dp2[i][i] = 0;
        sum[i] = sum[i-1] + val[i];
    }
    for(int l = 4;l <= n;l+=2){
        for(int i = 1;i + l - 1<= n;i++){
            int j = i + l - 1;
            for(int k1 = i;k1 <= j;k1 += 2){
                for(int k2 = k1 + 1;k2 <= j;k2 += 2){
                    dp[i][j] = min(dp[i][j],dp[i][k1] + dp[k1+1][k2] + dp[k2+1][j] + sum[j] - sum[i-1]);
                }
            }
        }
    }
    cout<<dp[1][n];
    return 0;
} 

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pr;
const double pi=acos(-1);
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define Rep(i,u) for(int i=head[u];i;i=Next[i])
#define clr(a) memset(a,0,sizeof a)
#define pb push_back
#define mp make_pair
#define putk() putchar(‘ ‘)
ld eps=1e-9;
ll pp=1000000007;
ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
ll gcd(ll a,ll b){return (!b)?a:gcd(b,a%b);}
ll read(){
    ll ans=0;
    char last=‘ ‘,ch=getchar();
    while(ch<‘0‘ || ch>‘9‘)last=ch,ch=getchar();
    while(ch>=‘0‘ && ch<=‘9‘)ans=ans*10+ch-‘0‘,ch=getchar();
    if(last==‘-‘)ans=-ans;
    return ans;
}
void put(ll a){
    if(a<0)putchar(‘-‘),a=-a;
    int top=0,q[20];
    while(a)q[++top]=a%10,a/=10;
    top=max(top,1);
    while(top--)putchar(‘0‘+q[top+1]);
}
//head
#define INF 1000000000
#define N 410
int n,f1[N][N],f2[N][N],a[N];
int main(){
    freopen("merge.in","r",stdin);
    freopen("merge.out","w",stdout);
    n=read();
    rep(i,1,n)
        rep(j,1,n)f1[i][j]=f2[i][j]=INF;
    rep(i,1,n)a[i]=a[i-1]+read();
    rep(i,1,n)f2[i][i]=0;
    rep(i,1,n-1)f1[i][i+1]=a[i+1]-a[i-1];
    rep(len,3,n)
    rep(i,1,n-len+1){
        int j=i+len-1;
        rep(k,i,j-1)f2[i][j]=min(f2[i][j],f1[i][k]+f2[k+1][j]+a[j]-a[k]);
        rep(k,i,j-1)f1[i][j]=min(f1[i][j],f2[i][k]+f2[k+1][j]+a[j]-a[i-1]);
    }
    cout<<f2[1][n]<<endl;
    return 0;
}
时间: 2024-10-09 23:34:43

清北学堂模拟赛day7 石子合并加强版的相关文章

清北学堂模拟赛day7 数字碰撞

/* clj:水题别人都满分你不是你就完了,所以说水题一定要细心一点,有这么几个细节:①前导零的处理,全是零的时候要特判②换行要注意,不要多大一行,剩下就是水水的模拟了 */ #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #

清北学堂模拟赛day7 错排问题

/* 考虑一下已经放回m本书的情况,已经有书的格子不要管他,考虑没有书的格子,不考虑错排有(n-m)!种,在逐步考虑有放回原来位置的情况,已经放出去和已经被占好的格子,不用考虑,剩下全都考虑,设t=x∩y,把除t以外的搞一下容斥就行了 */ #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<c

清北学堂模拟赛d1t6 或和异或(xor)

题目描述 LYK最近在研究位运算,它研究的主要有两个:or和xor.(C语言中对于|和^) 为了更好的了解这两个运算符,LYK找来了一个2^n长度的数组.它第一次先对所有相邻两个数执行or操作,得到一个2^(n-1)长度的数组.也就是说,如果一开始时a[1],a[2],-,a[2^n],执行完第一次操作后,会得到a[1] or a[2],a[3] or a[4] ,-, a[(2^n)-1] or a[2^n]. 第二次操作,LYK会将所有相邻两个数执行xor操作,得到一个2^(n-2)长度的数

清北学堂模拟day4 传球接力

[问题描述]n 个小朋友在玩传球. 小朋友们用 1 到 n 的正整数编号. 每个小朋友有一个固定的传球对象,第 i 个小朋友在接到球后会将球传给第 ai个小朋友, 并且第 i 个小朋友与第 ai个小朋友之间的距离为 di.一次传球接力是这样进行的:由一个小朋友发球,将球传给他的传球对象,之后接到球的小朋友再将球传给自己的传球对象,如此传球若干次后停止. 期间,包括发球者在内,每个小朋友至多只能拿到球一次. 一次传球接力的总距离是每次传球的距离的总和.小朋友们想进行一次总距离最长的传球接力,现在需

清北学堂模拟day4 业务办理

[问题描述]在银行柜台前,有 n 个顾客排队办理业务. 队伍中从前往后,第 i 位顾客办理业务需要ti 分钟时间. 一位顾客的等待时间定义为:队伍中在他之前的所有顾客和他自己的办理业务时间的总和.第 i 位顾客有一个最长等待时间 di,如果超过了时间 di, 业务还没有办理完成,那么这位顾客就会觉得不满意. 具体来说, 假设第 i 位顾客的等待时间为 fi,若 fi > di, 则这位顾客的不满意度为 fi-di,否则不满意度为 0.你作为银行里的职员,需要安排这 n 位顾客的初始排队顺序,使得

清北学堂2017NOIP冬令营入学测试 P4744 A’s problem(a)

清北学堂2017NOIP冬令营入学测试 P4744 A's problem(a) 时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试题,每三天结算一次成绩.参与享优惠 描述 这是一道有背景的题目,小A也是一个有故事的人.但可惜的是这里纸张太小,小A无法把故事详细地说给大家听.可能小A自己也讲不清楚自己的故事,因为如果讲清了,也就没有这道题目了-- 小A的问题是这个样子,它找到了n份不同的工作,第i份工作每个月有ai的工资,每份工作需要小A每天

铁轨 清北学堂 线段树

铁轨 清北学堂 线段树 [题目描述] R 国的铁轨经常会进行重新修建. R 国是一个细长的国家,一共有 n 个城市排成一排,首都位于 1 号城市,相邻两个城市之间有铁路相连. 每次新建铁轨的时候,一定是从首都开始修建,直到某一个城市为止,这其间的铁路都会变成新版本的设 施,而旧设施会被拆除.然而,由于 R 国的工程师脑子不太好使,任意两种不同版本的铁路之间都无法连 接,因此必须要进行换乘. 现在给出你修建铁轨的操作,小 R 时不时第会想问你,如果在第 x 个城市到第 y 个城市之间随机选择一个

济南清北学堂游记 Day 5.

十一月的第一天.算下来在济南已经呆了接近一星期了...... 还剩九天...看着洛谷的倒计时心里直发慌. 也许我不该过多纠结于高级算法,基础也是很重要的. 今天晚上就自由的敲一些板子吧.最后的九天,让自己不能留有遗憾才行. 今天的模拟赛就整体来说...较往常持平,依然是T1可写正解 T2 T3暴力...可暴力总是写挂...只有两个半小时时间也很难抽出时间对拍.. (今天借rqy的机械键盘用了一下,哇这个是真的用起来爽...这个青轴的声音听起来让人上瘾..) 明天还不知会有什么更加难写的题,加油吧

济南清北学堂游记 Day 7.

完结撒花? 最后的模拟赛与讲题.大家似乎仍然乐在其中,虽然看评测结果,仍然是满地红. 其实到了最后已经是没有多少可写的了..... 一个精彩的地方是晚上填表的时候,群里炸锅了已经.到处都在刷CCL老师的表情23333 (CCL表示让他们疯去吧) 大概的想了想这几天的内容,在最后的七天里,要做的事情还有很多. (学校模拟赛的出题任务又甩给我了...星期天就要比的..) 先列一些出来吧. 11.4 搞三个题,如果有时间就复习一下排序 查找 二分等基础操作. 11.5 树与图的相关算法(包括新增的二分