NOIP2018提高组模拟9.18

本文解析了两道算法竞赛题目,包括小A的任务和小p的属性,提供了多种解题策略,从基本枚举到高级DP优化,详细阐述了如何在限定时间内找到最优解。

【jzoj 5872】小 A 的任务
(File IO): input:problem.in $ \quad $ output:problem.out
Time Limits: 5000 ms $ \quad $ Memory Limits: 524288 KB Detailed Limits

Description

pic

Input

pic

Output

pic

Sample Input

 3 
 1 2 3 

Sample Output

 624 
 3

 

Data Constraint

对于 10%的数据,保证 $ n< 5 $
对于 40%的数据,保证 $ n<10 $
对于 70%的数据,保证 $ n<500 $
对于 100%的数据,保证 $ n \le 10^7, 1 \le s_i \le n $
 

题解

方法1:枚举每个任务选择,再枚举所有的三元组。
期望得分40

方法2:可以发现展开

\[ ( \frac{1}{s_i} + \frac{1}{s_j} + \frac{1}{s_k} ) \times ( s_i^2 + s_j^2 + s_k^2 ) \]

后得到

\[ s_i + s_j + s_k + \frac{s_j^2}{s_i} + \frac{s_k^2}{s_i} + \frac{s_i^2}{s_j} + \frac{s_k^2}{s_j} + \frac{s_i^2}{s_k} + \frac{s_j^2}{s_k} \]

根据排序不等式,顺序和 $ \ge $ 乱序和,重新整理后可得到

\[ s_i + s_j + s_k + \frac{s_j^2}{s_i} + \frac{s_k^2}{s_i} + \frac{s_i^2}{s_j} + \frac{s_k^2}{s_j} + \frac{s_i^2}{s_k} + \frac{s_j^2}{s_k} \]

\[ \ge s_i + s_j + s_k + \frac{s_i^2}{s_i} + \frac{s_i^2}{s_i} + \frac{s_j^2}{s_j} + \frac{s_j^2}{s_j} + \frac{s_k^2}{s_k} + \frac{s_k^2}{s_k} \]

\[ \ge 3 \times s_i + 3 \times s_j + 3 \times s_k \]

那么可以知道,任务一定是都要选,这样才能最大化优美程度。
期望得分65

方法3:注意到排序不等式的取等号条件,可以发现当所有都相同是无论是否选择任务优美程度都不会改变,
在最大化优美程度的基础上最小化选择的个数,此时所有的任务都不选择。
结合方法2,期望得分70

方法4:注意到统计的是所有的三元组,考虑分步计算贡献。由展开后的式子分为两部分进行计算

\[ s_i + s_j + s_k + \frac{s_j^2}{s_i} + \frac{s_k^2}{s_i} + \frac{s_i^2}{s_j} + \frac{s_k^2}{s_j} + \frac{s_i^2}{s_k} + \frac{s_j^2}{s_k} \]

令 $ sum = \sum_{i=1}^n s_i , inv_{sum} = \sum_{i=1}^n \frac{1}{s_i}, sqr_{sum} = \sum_{i=1}^n s_i^2 $

容易得到 $ Ans=3 \times n^2 \times sum + 6 \times n \times inv_{sum} \times sqr_{sum} $
注意到 $ s_i \le n $ 所以可以 $ O(n) $ 预处理逆元后计算,复杂度 $ O(n) $ ,时限非常宽
结合方法3,期望得分100

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
#define Mod 1000000007
ll read(){
    char ch; ll x=0;
    while(ch=getchar(),ch<'0'||ch>'9');x=ch-48;
    while(ch=getchar(),ch>='0'&&ch<='9')x=10*x+ch-48;
    return x;
}
int n;
ll s[10000005],sum1,sum2,sum3,ans;
ll qpow(ll x,ll k){
    ll res=1; 
    while(k>0){
        if(k&1) res=res*x%Mod;
        x=x*x%Mod;
        k>>=1;
    }
    return res%Mod;
}
signed main(){
    freopen("problem.in","r",stdin);
    freopen("problem.out","w",stdout);
    scanf("%d",&n); bool f=1; int pre=-1;
    for(int i=1;i<=n;++i){
        s[i]=read();
        sum1=(sum1+s[i])%Mod;
        sum2=(sum2+s[i]*s[i]%Mod)%Mod;
        sum3=(sum3+qpow(s[i],Mod-2))%Mod;
        if(i>1&&pre!=s[i]) f=0;
        pre=s[i];
    }
    ans=(3*n%Mod*n%Mod*sum1%Mod+6*n%Mod*sum2%Mod*sum3%Mod)%Mod;
    printf("%lld\n",ans);
    if(!f) printf("%d",n); else puts("0");
    return 0;
}

【jzoj 5873】小p的属性
(File IO): input:growth.in $ \quad $ output:growth.out
Time Limits: 1000 ms $ \quad $ Memory Limits: 524288 KB Detailed Limits

Description

pic

Input

输入包括两行
第一行两个整数 $ n, m $
接下来 $ n $ 行,每行三个整数 $ x_i, y_i, z_i $
 

Output

输出包括一行
输出一个整数表示答案
 

Sample Input

 2 4 
 2 1 10 
 1 2 20 

Sample Output

 50 

Data Constraint

pic

题解

方法1:枚举每天升级哪一种属性
期望得分20

方法2:注意到 $ n \le 10 $ ,考虑建立矩阵?,然后矩阵快速幂
期望得分40

方法3:注意到 $ m \le 1000 $ ,考虑 $ dp $ ,
$ dp[I][j] $ 表示前 $ i $ 天, $ a $ 属性到 $ j $ 的最大得分, 简单转移即可
结合方法2,期望得分60

方法4:注意到 $ x_i, y_i \le 1000 $ ,考虑前 $ 2000 $ 后每一天一定可以得到每一个奖励的分数,
前2000天 $ dp $ 转移,之后 $ O(1) $ 计算即可
结合方法2,期望得分80

方法5:注意到许多 $ dp $ 状态是无用的,且两个有用的 $ dp $ 状态之间可以 $ O(1) $ 转移,
考虑类似离散化的思想,只关心 $ dp $ 状态表示的 $ (a, b) $ 为某一个奖励的 $ (x_i, y_i ) $ ,转移即可
复杂度 $ O(n^2) $ ,期望得分100

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
int read(){
    char ch; int x=0;
    while(ch=getchar(),ch<'0'||ch>'9');x=ch-48;
    while(ch=getchar(),ch>='0'&&ch<='9')x=10*x+ch-48;
    return x;
}
struct node{ int x,y,z; }a[1005],b[1005];
bool cmp1(node x,node y){ return x.x<y.x; }
bool cmp2(node x,node y){ return x.y<y.y; }
int n,m;
ll f[1005][1005],g[1005][1005],ans;
int main(){
    freopen("growth.in","r",stdin);
    freopen("growth.out","w",stdout);
    n=read(); m=read();
    for(int i=1;i<=n;++i){ 
        a[i].x=read(); a[i].y=read(); a[i].z=read(); 
        b[i]=a[i];
    }
    sort(a+1,a+1+n,cmp1);
    sort(b+1,b+1+n,cmp2);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j){
            int x=a[i].x,y=b[j].y;
            if(x+y>m) break;
            if(b[j].x<=x) g[i][j]=g[i][j-1]+b[j].z;
            else g[i][j]=g[i][j-1];
            f[i][j]=max(f[i-1][j]+g[i-1][j]*(x-a[i-1].x-1),f[i][j-1]+g[i][j-1]*(y-b[j-1].y-1))+g[i][j];
            ans=max(ans,g[i][j]*(m-x-y)+f[i][j]);
        }
    printf("%lld",ans);
    return 0;
}

转载于:https://www.cnblogs.com/PotremZ/p/Test20180927.html

于2024年4月-2025年9月期间,研究团队在贵州习水国家级自然保护区制定39条样线,涵盖灌木林、常绿阔叶林、针叶林、常绿落叶阔叶混交林、针阔混交林等不同植被类型,每条样线分春夏秋冬4个季节采集样品,用真菌采集软件记录经纬度、海拔、采集地点、时间、生境等信息,使用佳能相机(R6 mark Ⅱ)对大型真菌进行拍照,并采集标本,标本存放于贵州省生物研究所大型真菌标本馆(HGAMF)。 通过形态学初步鉴定,结合分子生物学最终鉴定,参考已]报道的中国毒蘑菇名录开展毒蘑菇的认定。 调查到保护区内有毒真菌7目25科64种,导致中毒的主要类型有急性肾衰竭型、神经精神型和胃肠炎型。最终形成贵州习水国家级自然保护区大型有毒真菌图片数据集,它由以下2个部分成。 (1)附件1包含78张原始照片(.JPG),照片名字包括了大型有毒真菌的拉丁名和中文名,若无中文名的直接用拉丁名。 (2)附件2是一个压缩文件,包含了2张工作表,其中一张表是大型有毒真菌39条样线的信息,另一张表是大型有毒真菌的中毒类型。 照片采用佳能相机R6 mark Ⅱ拍摄,物种鉴定通过多种文献核实,并经两位以上专家鉴定确认。该数据集可为研究地及周边的普通人识别有毒大型真菌提供参考,通过及时的图片对比,能有效避免误采误食大型有毒真菌,同时为因误食大型真菌可能引发的身体损伤进行了总结,能为患者及时治疗提供参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值