期望得分:100+100+50=250

实际得分:100+70+50=220

T1 最大值(max)

Time Limit:1000ms   Memory Limit:128MB

题目描述

LYK有一本书,上面有很多有趣的OI问题。今天LYK看到了这么一道题目:

这里有一个长度为n的正整数数列ai(下标为1~n)。并且有一个参数k。

你需要找两个正整数x,y,使得x+k<=y,并且y+k-1<=n。并且要求a[x]+a[x+1]+…+a[x+k-1]+a[y]+a[y+1]+…+a[y+k-1]最大。

LYK并不会做,于是它把题扔给了你。

输入格式(max.in)

第一行两个数n,k。

第二行n个数,表示ai。

输出格式(max.out)

两个数表示x,y。若有很多种满足要求的答案,输出x最小的值,若x最小仍然还有很多种满足要求的答案,输出y最小的值。

输入样例

5 2

6 1 1 6 2

输出样例

1 4

对于30%的数据n<=100。

对于60%的数据n<=1000

对于100%的数据1<=n<=100000,1<=k<=n/2,1<=ai<=10^9。

维护连续的k个数的和 的后缀最大值

#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 100001
using namespace std;
typedef long long LL;
LL sum[N],p[N],suf[N];
int pos[N];
void read(LL &x)
{x=0; char c=getchar();while(!isdigit(c)) c=getchar();while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}
int main()
{freopen("max.in","r",stdin);freopen("max.out","w",stdout);int n,k;scanf("%d%d",&n,&k);for(int i=1;i<=n;i++) read(sum[i]),sum[i]+=sum[i-1];for(int i=1;i+k-1<=n;i++) p[i]=sum[i+k-1]-sum[i-1];for(int i=n-k+1;i;i--) if(p[i]>=suf[i+1]) suf[i]=p[i],pos[i]=i;else suf[i]=suf[i+1],pos[i]=pos[i+1];int ansx,ansy;LL maxn=0;for(int i=1;i+k+k-1<=n;i++)if(p[i]+suf[i+k]>maxn) maxn=p[i]+suf[i+k],ansx=i,ansy=pos[i+k];else if(p[i]+suf[i+k]==maxn && ansy>pos[i+k]) ansy=pos[i+k];printf("%d %d",ansx,ansy);return 0;
}

View Code

T2 吃东西(eat)

Time Limit:2000ms   Memory Limit:1024MB

题目描述

一个神秘的村庄里有4家美食店。这四家店分别有A,B,C,D种不同的美食。LYK想在每一家店都吃其中一种美食。每种美食需要吃的时间可能是不一样的。

现在给定第1家店A种不同的美食所需要吃的时间a1,a2,…,aA。

给定第2家店B种不同的美食所需要吃的时间b1,b2,…,bB。

以及c和d。

LYK拥有n个时间,问它有几种吃的方案。

输入格式(eat.in)

第一行5个数分别表示n,A,B,C,D。

第二行A个数分别表示ai。

第三行B个数分别表示bi。

第四行C个数分别表示ci。

第五行D个数分别表示di。

输出格式(eat.out)

一个数表示答案。

输入样例

11 3 1 1 1

4 5 6

3

2

1

输出样例

2

对于30%的数据A,B,C,D<=50

对于另外30%的数据n<=1000。

对于100%的数据1<=n<=100000000,1<=A,B,C,D<=5000,0<=ai,bi,ci,di<=100000000。

30% 枚举,另外30%分组背包

100%的数据:注意空间1GB

所以可以维护sum[i]表示 C+D 里面时间和为i 的方案数

然后枚举A,B,累计n-A[i]-B[i] 的方案数

#include<map>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long LL;
LL dp[5][1001];
int cost[5][5001],n;
int C[5001],D[5001],A[5001],B[5001];
int sum[200000001];
inline void read(int &x)
{x=0; char c=getchar();while(!isdigit(c)) c=getchar();while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}
void init()
{read(n); read(cost[1][0]); read(cost[2][0]); read(cost[3][0]); read(cost[4][0]);for(int i=1;i<=cost[1][0];i++) read(cost[1][i]);for(int i=1;i<=cost[2][0];i++) read(cost[2][i]);for(int i=1;i<=cost[3][0];i++) read(cost[3][i]);for(int i=1;i<=cost[4][0];i++) read(cost[4][i]);
}
void out(LL x)
{if(x/10) out(x/10);putchar(x%10+'0');
}
void work1()
{for(int i=0;i<=n;i++) dp[0][i]=1;for(int k=1;k<=4;k++)for(int i=1;i<=n;i++)for(int j=1;j<=cost[k][0];j++)if(i-cost[k][j]>=0) dp[k][i]+=dp[k-1][i-cost[k][j]];out(dp[4][n]);
}
void work2()
{int ans=0;for(int i=1;i<=cost[1][0];i++)for(int j=1;j<=cost[2][0];j++)for(int k=1;k<=cost[3][0];k++)for(int l=1;l<=cost[4][0];l++)if(cost[1][i]+cost[2][j]+cost[3][k]+cost[4][l]<=n) ans++;printf("%d",ans);
}
void work3()
{int cnt=0,sc=cost[3][0],sd=cost[4][0]; for(int i=1;i<=sc;i++) C[i]=cost[3][i];for(int i=1;i<=sd;i++) D[i]=cost[4][i]; int minn=2e8,maxn=0 ;for(int i=1;i<=sc;i++)for(int j=1;j<=sd;j++){sum[C[i]+D[j]]++;minn=min(minn,C[i]+D[j]);maxn=max(maxn,C[i]+D[j]); }for(int i=minn;i<=maxn;i++) sum[i]+=sum[i-1];int sa=cost[1][0],sb=cost[2][0]; for(int i=1;i<=sa;i++) A[i]=cost[1][i];for(int i=1;i<=sb;i++) B[i]=cost[2][i];long long ans=0; for(int i=1;i<=sa;i++)for(int j=1;j<=sb;j++)if(n-A[i]-B[j]>=0) ans+=sum[min(n-A[i]-B[j],maxn)];out(ans);
}
int main()
{freopen("eat.in","r",stdin);freopen("eat.out","w",stdout); init();if(cost[1][0]<=50 && cost[2][0]<=50 && cost[3][0]<=50 && cost[4][0]<=50) work2();else if(n<=1000) work1();else work3(); return 0;
}

View Code

考场上分组背包 体积从1开始的,挂了

数据里面有0

T3  分糖果(candy)

Time Limit:1000ms   Memory Limit:128MB

题目描述

总共有n颗糖果,有3个小朋友分别叫做L,Y,K。每个小朋友想拿到至少k颗糖果,但这三个小朋友有一个共同的特点:对3反感。也就是说,如果某个小朋友拿到3颗,13颗,31颗,333颗这样数量的糖果,他就会不开心。(也即它拿到的糖果数量不包含有一位是3)

LYK掌管着这n颗糖果,它想问你有多少种合理的分配方案使得将这n颗糖果全部分给小朋友且没有小朋友不开心。

例如当n=3,k=1时只有1种分配方案,当n=4,k=1时有3种分配方案分别是112,121,211。当n=7,k=2时则不存在任何一种合法的方案。

当然这个答案可能会很大,你只需输出答案对12345647取模后的结果就可以了。

输入格式(candy.in)

第一行两个数表示n,k。

输出格式(candy.out)

一个数表示方案总数。

输入样例

99999 1

输出样例

9521331

对于30%的数据n<=100

对于50%的数据n<=1000。

对于另外30%的数据k=1。

对于100%的数据3<=n<=10^10000,1<=k<=n/3,且n,k不包含前导0。

数位DP

dp[i][j][k][l][t] 表示n的前i位,分完后的余数为j,第1/2/3个小朋友的第i位能否随便填 的方案数

再枚举3个小朋友分别分多少转移

#include<cstdio>
#include<cstring>#define N 10003using namespace std;const int mod=12345647;char s[N];
int a[N],b[N],dp[N][3][2][2][2];void ADD(int &i,int j)  {  i+=j; if(i>=mod) i-=mod; }int main()
{freopen("candy.in","r",stdin);freopen("candy.out","w",stdout);scanf("%s",s+1); int len1=strlen(s+1);for(int i=1;i<=len1;++i) a[i]=s[i]-'0';scanf("%s",s+1); int len2=strlen(s+1);for(int i=1;i<=len2;++i) b[i+len1-len2]=s[i]-'0';dp[0][0][0][0][0]=1;int i,j,k,l,t,I,J,K,L,T;for(i=0;i<len1;i++)for(j=0;j<3;j++)for(k=0;k<2;k++)for(l=0;l<2;l++)for(t=0;t<2;t++)if(dp[i][j][k][l][t])for(int s1=0;s1<=9;s1++)if(s1!=3)for(int s2=0;s2<=9;s2++)if(s2!=3)for(int s3=0;s3<=9;s3++)if(s3!=3){I=i+1;J=j*10+a[i+1]-s1-s2-s3;if(J<0 || J>2) continue;if(!k && s1<b[i+1]) continue;K=(k || s1>b[i+1]);if(!l && s2<b[i+1]) continue;L=(l || s2>b[i+1]);if(!t && s3<b[i+1]) continue;T=(t || s3>b[i+1]);ADD(dp[I][J][K][L][T],dp[i][j][k][l][t]);                    }int ans=0;for(k=0;k<2;k++)for(l=0;l<2;l++)for(t=0;t<2;t++)ADD(ans,dp[len1][0][k][l][t]);printf("%d",ans);
}

View Code

考场50分做法:枚举第一个,枚举第二个,判断是否合法

#include<cstdio>
using namespace std;
bool check(int k)
{while(k){if(k%10==3) return false;k/=10;}return true;
}
int main()
{freopen("candy.in","r",stdin);freopen("candy.out","w",stdout);int n,k,ans=0;scanf("%d%d",&n,&k);for(int i=k;i+k+k<=n;i++)if(check(i))for(int j=k;j+i+k<=n;j++)if(check(j)&&check(n-i-j)) ans++;printf("%d",ans);return 0;
}

View Code

转载于:https://www.cnblogs.com/TheRoadToTheGold/p/7639547.html

2017北京国庆刷题Day2 afternoon相关推荐

  1. 2017北京国庆刷题Day5 afternoon

    期望得分:100+60+100=260 实际得分:0+60+40=100 设图中有m个环,每个环有si条边,有k条边不在环中 ans= (2^s1 -2)*( 2^s2 -2)* (2^s3 -2)- ...

  2. 2017北京国庆刷题Day5 morning

    期望得分:0+60+60=120 实际得分:0+30+60=90 令g=gcd(X11,X12,X13--) 则行列式可能为D的充要条件为g|D 1.g|D为必要条件: 由定义来算行列式的时候,每一项 ...

  3. 【c++刷题Day2】专题3栈与队列单调栈与单调队列T3

    这是C++刷题的Day2

  4. 对于清北学堂2018国庆刷题班的学习总结

    \(10.1\) 例题1: 最多因子数(Link) 给定一个区间\([L, R]\),要求求出在区间内拥有最大因子数的数. 定义\(F(X)\)为\(X\)的因子个数函数.首先我们要知道,对于任意一个 ...

  5. 【套题】qbxt国庆刷题班D1

    Day1 事实上D1的题目还是比较简单的= =然而D1T2爆炸了就十分尴尬--错失一波键盘 看题 T1 传送门 Description 现在你手里有一个计算器,上面显示了一个数\(S\),这个计算器十 ...

  6. LeetCode C语言刷题——day2

    目录 一.删除排序列表中的重复元素 1.题目描述 2.题解 3.源码 二.二叉树的最大深度 1.题目描述 2.题解 3.源码 三.将有序数组转换成二叉搜素树 1.题目描述 2.题解 3.源码 四.将二 ...

  7. LeetCode MySQL刷题——day2

    目录 一.上升的温度 1.题目描述 2.题解 3.源码 二.大的国家 1.题目描述 2.题解 ​ 3.源码 三.超过五名学生的课 1.题目描述 2.题解 3.源码 四.有趣的电影 1.题目描述 2.题 ...

  8. 2017 北京赛区 J题 Pangu and Stones 【区间DP】

    题目链接:https://vjudge.net/problem/HihoCoder-1636: 题意:n堆石子,每次可以合并连续的 [ L~R ]堆石子,求最少的代价: /* 思路:区间DP;dp[i ...

  9. 国庆作业 刷题0929

    国庆作业 刷题0929 使进度在90-95%截图上传 详情 第二本书 第一本书

最新文章

  1. vector与结构体联合使用 在磁盘中生成.txt 文件
  2. 马化腾:微信将被谁颠覆,领衔下一代互联网的终端居然是?
  3. 富有客户端技术之——jQuery EasyUI
  4. Elasticsearch 不同的搜索类型之间的区别
  5. OpenCV—中值滤波
  6. 关于使用idea工具debug时,断点颜色由红色变成灰色解决方法
  7. DevOps“兵器”60样,你都会使哪几样?
  8. Java基础---方法1
  9. 我的 IDEA 使用 配置策略
  10. c语言bmp转换jpeg_PDF格式转换工具
  11. mysql+分页脚本_MySql实现分页查询的SQL
  12. 使用ECMAScript 5严格模式提升开发效率
  13. XML解析模型(完整版)
  14. Java面向对象总复习-QuickHit
  15. 4个最受欢迎的大数据可视化工具
  16. POJ-3580-SuperMemo(splay的各种操作)
  17. 人脸识别算法一:特征脸方法(Eigenface)
  18. uniapp实现IM即时通讯仿微信聊天功能
  19. 心形源码HTML,纯CSS实现心形加载动画(附源码)
  20. 区分Linux:eth0,eth1,eth2,lo

热门文章

  1. could not find or load the Qt platform plugin xcb
  2. Android加密算法之AES加密和解密实现
  3. java 改文件名的例子
  4. 老李分享:HTTP协议之协议头
  5. c 无回显读取字符/不按回车即获取字符
  6. 11.25晚C语言答疑
  7. Git学习(四)标签管理
  8. OpenCV二值化cvThreshold和自适应二值化cvAdaptiveThreshold及Otsu
  9. zabbix 5.0所有依赖包_一杯茶的时间,上手Zabbix
  10. file watchers怎么默认打开_python怎么打印字符