2017北京国庆刷题Day2 afternoon
期望得分: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=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; 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=;i<=n;i++) read(sum[i]),sum[i]+=sum[i-];
for(int i=;i+k-<=n;i++) p[i]=sum[i+k-]-sum[i-];
for(int i=n-k+;i;i--)
if(p[i]>=suf[i+]) suf[i]=p[i],pos[i]=i;
else suf[i]=suf[i+],pos[i]=pos[i+];
int ansx,ansy;
LL maxn=;
for(int i=;i+k+k-<=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 ;
}
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[][];
int cost[][],n;
int C[],D[],A[],B[];
int sum[];
inline void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
}
void init()
{
read(n); read(cost[][]); read(cost[][]); read(cost[][]); read(cost[][]);
for(int i=;i<=cost[][];i++) read(cost[][i]);
for(int i=;i<=cost[][];i++) read(cost[][i]);
for(int i=;i<=cost[][];i++) read(cost[][i]);
for(int i=;i<=cost[][];i++) read(cost[][i]);
}
void out(LL x)
{
if(x/) out(x/);
putchar(x%+'');
}
void work1()
{
for(int i=;i<=n;i++) dp[][i]=;
for(int k=;k<=;k++)
for(int i=;i<=n;i++)
for(int j=;j<=cost[k][];j++)
if(i-cost[k][j]>=) dp[k][i]+=dp[k-][i-cost[k][j]];
out(dp[][n]);
}
void work2()
{
int ans=;
for(int i=;i<=cost[][];i++)
for(int j=;j<=cost[][];j++)
for(int k=;k<=cost[][];k++)
for(int l=;l<=cost[][];l++)
if(cost[][i]+cost[][j]+cost[][k]+cost[][l]<=n) ans++;
printf("%d",ans);
}
void work3()
{
int cnt=,sc=cost[][],sd=cost[][];
for(int i=;i<=sc;i++) C[i]=cost[][i];
for(int i=;i<=sd;i++) D[i]=cost[][i];
int minn=2e8,maxn= ;
for(int i=;i<=sc;i++)
for(int j=;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-];
int sa=cost[][],sb=cost[][];
for(int i=;i<=sa;i++) A[i]=cost[][i];
for(int i=;i<=sb;i++) B[i]=cost[][i];
long long ans=;
for(int i=;i<=sa;i++)
for(int j=;j<=sb;j++)
if(n-A[i]-B[j]>=) 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[][]<= && cost[][]<= && cost[][]<= && cost[][]<=) work2();
else if(n<=) work1();
else work3();
return ;
}
考场上分组背包 体积从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 10003 using namespace std; const int mod=; char s[N];
int a[N],b[N],dp[N][][][][]; 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+); int len1=strlen(s+);
for(int i=;i<=len1;++i) a[i]=s[i]-'';
scanf("%s",s+); int len2=strlen(s+);
for(int i=;i<=len2;++i) b[i+len1-len2]=s[i]-'';
dp[][][][][]=;
int i,j,k,l,t,I,J,K,L,T;
for(i=;i<len1;i++)
for(j=;j<;j++)
for(k=;k<;k++)
for(l=;l<;l++)
for(t=;t<;t++)
if(dp[i][j][k][l][t])
for(int s1=;s1<=;s1++)
if(s1!=)
for(int s2=;s2<=;s2++)
if(s2!=)
for(int s3=;s3<=;s3++)
if(s3!=)
{
I=i+;
J=j*+a[i+]-s1-s2-s3;
if(J< || J>) continue;
if(!k && s1<b[i+]) continue;
K=(k || s1>b[i+]);
if(!l && s2<b[i+]) continue;
L=(l || s2>b[i+]);
if(!t && s3<b[i+]) continue;
T=(t || s3>b[i+]);
ADD(dp[I][J][K][L][T],dp[i][j][k][l][t]);
}
int ans=;
for(k=;k<;k++)
for(l=;l<;l++)
for(t=;t<;t++)
ADD(ans,dp[len1][][k][l][t]);
printf("%d",ans);
}
考场50分做法:枚举第一个,枚举第二个,判断是否合法
#include<cstdio>
using namespace std;
bool check(int k)
{
while(k)
{
if(k%==) return false;
k/=;
}
return true;
}
int main()
{
freopen("candy.in","r",stdin);
freopen("candy.out","w",stdout);
int n,k,ans=;
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 ;
}
2017北京国庆刷题Day2 afternoon的更多相关文章
- 2017北京国庆刷题Day1 afternoon
期望得分:100+100+100=300 实际得分:100+100+100=300 T1 一道图论好题(graph) Time Limit:1000ms Memory Limit:128MB 题目 ...
- 2017北京国庆刷题Day5 afternoon
期望得分:100+60+100=260 实际得分:0+60+40=100 设图中有m个环,每个环有si条边,有k条边不在环中 ans= (2^s1 -2)*( 2^s2 -2)* (2^s3 -2)… ...
- 2017北京国庆刷题Day2 morning
期望得分:100+100+40=240 实际得分:100+40+0=140 T1 一道图论神题(god) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK ...
- 2017北京国庆刷题Day4 afternoon
期望得分:100+100+0=200 实际得分:5+0+0=5 每加入一个数,x的因数位置++ 注意:根号x枚举时,如果x是完全平方数,根号x会重复累计2次,要减去 考场上没减,5分 /(ㄒoㄒ)/~ ...
- 2017北京国庆刷题Day6 afternoon
期望得分:100+100+40=240 实际得分:100+0+40=140 二进制拆分.二进制前缀和 #include<cstdio> #include<iostream> u ...
- 2017北京国庆刷题Day3 afternoon
期望得分:100+0+30=130 实际得分:100+36.5+0=136.5 T3 一个变量写混了,丢了30.. 模拟栈 #include<cstdio> #include<cst ...
- 2017北京国庆刷题Day7 afternoon
期望得分:100+30+100=230 实际得分:60+30+100=190 排序去重 固定右端点,左端点单调不减 考场上用了二分,没去重,60 #include<cstdio> #inc ...
- 2017北京国庆刷题Day7 morning
期望得分:100+0+100=200 实际得分:100+20+0=120 离散化搞搞 #include<cstdio> #include<iostream> #include& ...
- 2017北京国庆刷题Day3 morning
期望得分:100+60+0=160 实际得分:100+30+0=130 考场上用的哈希 #include<cstdio> #include<cstring> #include& ...
随机推荐
- 关于解决MySort
关于解决MySort 那天老师教给我们关于sort的用法以及String类中的split方法.在一定程度上告诉我们sort用法的原理和一些特别的用法后,老师叫我们用JAVA尝试去设计一个"M ...
- 对懂球帝ios版的用户体验
用户界面: 主页面是资讯页面 这个设计很棒 对球迷来说 每天最关注的就是 我的主队赢了输了 其次界面以绿色为主 很有绿茵场的感觉 很符合足球狗的口味 记住用户的选择: 这个应用 有一个 球队的关注 选 ...
- 软工1816 · BETA 版冲刺前准备
任务博客 组长博客 总的来讲Alpha阶段我们计划中的工作是如期完成的.不过由于这样那样的原因,前后端各个任务完成度不算非常高,距离完成一个真正好用.完美的软件还有所差距. 过去存在的问题 测试工作未 ...
- Codeforces Round #312 (Div. 2) E. A Simple Task 线段树+计数排序
题目链接: http://codeforces.com/problemset/problem/558/E E. A Simple Task time limit per test5 secondsme ...
- ACM 第二十天
积性函数.杜教筛 练习题 莫比乌斯函数之和 51Nod - 1244 莫比乌斯函数,由德国数学家和天文学家莫比乌斯提出.梅滕斯(Mertens)首先使用μ(n)(miu(n))作为莫比乌斯函数的记号. ...
- java下执行mongodb
1.1连单台mongodb Mongo mg = newMongo();//默认连本机127.0.0.1 端口为27017 Mongo mg = newMongo(ip);//可以指定ip 端口默认 ...
- .NET中的堆(Heap)和栈(Stack)的本质
计算机的内存可以分为代码块内存,Stack内存和Heap内存.代码块内存是在加载程序时存放程序机器代码的地方. 栈(Stack)一般存放函数内的局部变量. 堆(Heap)一般存放全局变量和类对象实例等 ...
- Windows下多线程编程(一)
前言 熟练掌握Windows下的多线程编程,能够让我们编写出更规范多线程代码,避免不要的异常.Windows下的多线程编程非常复杂,但是了解一些常用的特性,已经能够满足我们普通多线程对性能及其他要求. ...
- [LeetCode] [LeetCode] Populating Next Right Pointers in Each Node II
Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...
- bzoj3622-已经没有什么好害怕的的了
题意 给出两个长度为 \(n\) 的数列 \(a,b\) ,\(2n\) 个数都互不相同,求有多少种对应方式使得 \(a_i>b_i\) 的个数比 \(a_i<b_i\) 的个数恰好多 \ ...