期望得分:100+30+100=230

实际得分:100+30+70=200

T3 数组开小了 。。。。。

记录 1的前缀和,0的后缀和

枚举第一个1的出现位置

#include<cstdio>
#include<cstring>
#include<algorithm> #define N 100002 using namespace std; char s[N]; int num[N]; int suf0[N],pre1[N]; int main()
{
freopen("reverse.in","r",stdin);
freopen("reverse.out","w",stdout);
scanf("%s",s+);
int len=strlen(s+);
for(int i=;i<=len;i++) num[i]=s[i]-'';
for(int i=;i<=len;i++) pre1[i]=pre1[i-]+num[i];
for(int i=len;i;i--) suf0[i]=suf0[i+]+(!num[i]);
int ans=len;
for(int i=;i<=len;i++) ans=min(ans,pre1[i-]+suf0[i]);
ans=min(ans,pre1[len]);
printf("%d",ans);
}

从1——n枚举一遍

二进制表示它有哪些数出现过了,相当于哈希

然后Σ C(i,2)

#include<cstdio>

using namespace std;

int  f[];

void count(int x)
{
int s=;
while(x)
{
s|=<<x%;
x/=;
}
f[s]++;
} int main()
{
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
int n;
scanf("%d",&n);
for(int i=;i<=n;i++) count(i);
long long ans=;
for(int i=;i<=;i++) ans+=1ll*f[i]*(f[i]-)/;
printf("%I64d",ans);
}

考场思路:

种类只有2^9种可能

所以枚举每一种可能

那问题转化为了 有x种数,用它来组成<=n的数的方案数

开始想裸的数位DP,但它不能保证所有的x种数都用上

然后又改的状压DP,dp[i][j] 表示填了i位,使用数的状态为j,

虽然能保证所有的x种数都用上,但数位DP的作用难以体现:

若枚举这一位填哪个数,因为不知道前面填了什么,所以也不能确定这一位填什么

脑补的改进方法是 数位DP加一维表示状态,状压DP加一维表示上一位填了什么

可行性未知

考场错误的状压DP

#include<cstdio>
#include<cstring> using namespace std; int tmp[],num[]; int use[],dp[][];
int a[],b[]; int main()
{
int n,len=;
scanf("%d",&n);
if(n<) { printf(""); return ; }
while(n) { tmp[++len]=n%; n/=;}
for(int i=len,len=;i;i--) num[++len]=tmp[i];
int tot,sum,T; long long ans=;
num[]=;
for(int s=;s<;s++)
{
if(s==)
{
int sad=;
}
memset(use,false,sizeof(use)); tot=;
memset(b,,sizeof(b));
memset(dp,,sizeof(dp));
for(int i=;i<;i++) if(s&(<<i)) tot++,use[i]=true,b[i]=tot;
T=<<tot;
for(int i=;i<=tot;i++) dp[][<<i-]=;
for(int i=;i<len;i++)
for(int t=T-;t;t=t&(t-))
for(int j=;j<=num[i+];j++)
if(use[j]) dp[i+][t|<<b[j]-]+=dp[i][t];
tot=; for(int i=;i<=len;i++) tot+=dp[i][T-];
ans+=1ll*tot*(tot-)/;
if(tot) printf("%d %d\n",s,tot);
}
printf("%I64d\n",ans);
}

考场错误的数位DP

#include<cstdio>
#include<cstring> using namespace std; int tmp[],num[]; int dp[][][][];
bool use[]; int main()
{
int n,len=;
scanf("%d",&n);
if(n<) { printf(""); return ; }
while(n) { tmp[++len]=n%; n/=;}
for(int i=len,len=;i;i--) num[++len]=i;
int S=<<; long long tot,ans=;
for(int s=S-;s;s=s&(s-))
{
memset(use,false,sizeof(use));
memset(dp,,sizeof(dp));
for(int i=;i<;i++)
if(s&(<<i)) use[i]=true;
for(int i=;i<;i++) dp[][i][]=;
for(int i=;i<len;i++)
for(int j=;j<;j++)
for(int k=;k<;k++)
if(k)
for(int l=;l<=num[i];l++) dp[i+][l][]+=dp[i][j][];
else
for(int l=;l<;l++)
if(l==num[i]) dp[i+][l][]+=dp[i][j][];
else dp[i+][l][]+=dp[i][j][];
tot=;
for(int i=;i<=len;i++)
for(int j=;j<;j++)
{
tot+=dp[i][j][]+dp[i][j][];
printf("%d %d\n",dp[i][j][],dp[i][j][]);
} ans+=tot*(tot+)/;
}
printf("%I64d\n",ans);
}

30暴力

#include<cstdio>
#include<cstring> bool visx[];
bool visy[]; using namespace std; int main()
{
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
int n;
scanf("%d",&n);
int X,Y,sx,sy,ans=;
bool ok;
for(int x=;x<n;x++)
{
X=x;
while(X)
{
if(!visx[X%]) visx[X%]=true;
X/=;
}
for(int y=x+;y<=n;y++)
{
Y=y;
while(Y)
{
if(!visy[Y%]) visy[Y%]=true;
Y/=;
}
ok=true;
for(int i=;i< && ok;i++)
if(visx[i]!=visy[i]) ok=false;
ans+=ok;
memset(visy,,sizeof(visy));
}
memset(visx,,sizeof(visx));
}
printf("%d",ans);
}

贪心

肯定是上升的时候,越大越好

下降的时候,越小越好

所以有了初步思路:

每次找连续下降的最后一个,然后找连续上升的最后一个,循环往复

看似很正确

但请看下图:

假设k=2,如果按上面的思路,那么后面会选上9

接下来要找连续下降 9后面那个点和8都不满足k=2的差值

所以我们得到的答案=4

但最优解是不要9,选后面的12和8

因为9后面的那个点不能下降,所以到了12仍然是处于上升,所以12比9更优

所以,我们不能找连续的序列,而是

只要现在处于上升阶段,就找最大的

只要现在处于下降阶段,就找最小的

幸亏打了暴力,对拍拍出了这个bug

#include<algorithm>
#include<cstdio>
#include<iostream> #define N 1000001 using namespace std; int e[N]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} int main()
{
freopen("wave.in","r",stdin);
freopen("wave.out","w",stdout);
int n,k;
read(n); read(k);
for(int i=;i<=n;i++) read(e[i]);
bool up=true;
int now,len=;
for(now=;now<=n && e[now+]<=e[now];now++);
int last=e[now++];
while(now<=n)
{
if(!up)
{
while(now<=n)
{
if(last-e[now]>=k) { last=e[now]; len++; up^=; break; }
else if(e[now]>=last ) last=e[now];
now++;
}
}
else
{
while(now<=n)
{
if(e[now]-last>=k) { last=e[now]; len++; up^=; break; }
else if(e[now]<=last) last=e[now];
now++;
}
}
now++;
}
printf("%d",len);
}

对拍代码(n^2)

#include<cstdio>
#include<iostream>
#include<algorithm> #define N 1000001 using namespace std; int f[N][],a[N]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} int main()
{
freopen("data.in","r",stdin);
freopen("std.out","w",stdout);
int n,k;
read(n); read(k);
for(int i=;i<=n;++i) read(a[i]);
int mx,ans=;
for(int i=;i<=n;i++)
{
mx=;
for(int j=i-;j;j--)
if(a[j]-a[i]>=k) mx=max(mx,f[j][]);
f[i][]=mx+; ans=max(ans,f[i][]);
mx=;
for(int j=i-;j;j--)
if(a[i]-a[j]>=k) mx=max(mx,f[j][]);
if(mx)
{
f[i][]=mx+;
ans=max(ans,f[i][]);
}
}
printf("%d",ans);
}

2017 国庆湖南Day2的更多相关文章

  1. 2017 国庆湖南 Day5

    期望得分:76+80+30=186 实际得分:72+10+0=82 先看第一问: 本题不是求方案数,所以我们不关心 选的数是什么以及的选的顺序 只关心选了某个数后,对当前gcd的影响 预处理 cnt[ ...

  2. 2017 国庆湖南 Day6

    期望得分:100+100+60=260 实际得分:100+85+0=185 二分最后一条相交线段的位置 #include<cstdio> #include<iostream> ...

  3. 2017 国庆湖南 Day1

    卡特兰数 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ] ...

  4. 2017 国庆湖南 Day3

    期望得分:100+30+60=190 实际得分:10+0+55=65 到了233 2是奇数位 或223 第2个2是偶数位就会223 .233 循环 #include<cstdio> #de ...

  5. 2017 国庆湖南 Day4

    期望得分:20+40+100=160 实际得分:20+20+100=140 破题关键: f(i)=i 证明:设[1,i]中与i互质的数分别为a1,a2……aφ(i) 那么 i-a1,i-a2,…… i ...

  6. 学大伟业 2017 国庆 Day1

    期望得分:100+100+20=220 实际得分:100+100+20=220 (好久没有期望==实际了 ,~\(≧▽≦)/~) 对于 a........a 如果 第1个a 后面出现的第1个b~z 是 ...

  7. 2017国庆 清北学堂 北京综合强化班 Day1

    期望得分:60+ +0=60+ 实际得分:30+56+0=86 时间规划极端不合理,T2忘了叉积计算,用解析几何算,还有的情况很难处理,浪费太多时间,最后gg 导致T3只剩50分钟,20分钟写完代码, ...

  8. 长乐国庆集训Day2

    T1 连珠风暴 题目 [题目描述] 给定M种颜色的珠子,每种颜色珠子的个数均不限,将这些珠子做成长度为N的项链. 问能做成多少种不重复的项链.两条项链相同,当且仅当两条项链通过旋转或是翻转后能重合在一 ...

  9. 2017.10.1 国庆清北 D1T1 zhx的字符串题

    题目背景 2017国庆清北D1T1 题目描述 你是能看到第一题的 friends 呢. ——hja 何大爷对字符串十分有研究,于是天天出字符串题虐杀 zhx.何大爷今天为 字符串定义了新的权值计算方法 ...

随机推荐

  1. Java接口interface,匿名内部类

    接口 1.接口内部为 常量+公用的抽象方法.类必须实现接口中的所有方法 2.接口的语法格式:不写abstract会自动添加,可以继承多个接口 修饰符不能使private,protected [修饰符] ...

  2. Python:集合操作总结

    集合是一组无序排列的不重复元素集 [注]:集合的最大作用是对一个序列进行去重操作 一.集合的分类 在Python中集合分为两类,为可变集合(set)和不可变集合(frozenset).对于可变集合(s ...

  3. 学习调用第三方的WebService服务

    互联网上面有很多的免费webService服务,我们可以调用这些免费的WebService服务,将一些其他网站的内容信息集成到我们的应用中显示,下面就以查询国内手机号码归属地为例进行说明. 首先安利一 ...

  4. C#从一个窗体传递参数到另一个窗体的链接

    http://blog.sina.com.cn/s/blog_60d69ce00100eldt.html

  5. Beta结束感想

    我得到的: 管理一个9人团队的经验 与组内成员(大部分一开始并不认识)共同向同一个目标努力的宝贵经历 学会使用Github的organization来管理整个团队的代码 学会使用leangoo这样的协 ...

  6. PDO笔记

    <?php/* * 查询操作主要是PDO::query().PDO::exec().PDO::prepare().PDO::query()主要是用于有记录结果返回的操作,特别是SELECT操作, ...

  7. java 基础 --集合--013

    1, contains()方法底层依赖的是equals()方法,而定义的类中没有equal()方法,所以它会使用父类Object中的equals()方法,而Object的equals()方法比较的是地 ...

  8. 【.Net】C#获取Windows系统特殊文件夹的路径

    系统特殊文件夹是包含公共信息的文件夹,如“Program Files”.“Programs”.“System”或“Startup”.特殊文件夹在默认情况下由系统设置,或者由用户在安装 Windows ...

  9. collection 在创建迭代器后 不能在添加数据 否则会出现并发问题

    collection 在创建迭代器后 不能在添加数据 否则会出现并发问题

  10. 25个Java机器学习工具&库--转载

    本列表总结了25个Java机器学习工具&库: 1. Weka集成了数据挖掘工作的机器学习算法.这些算法可以直接应用于一个数据集上或者你可以自己编写代码来调用.Weka包括一系列的工具,如数据预 ...