您的位置:首页 > 其它

【集训第六天·考试+数位】考试真心用不上算法~~~~~~~~~

2017-04-07 08:30 218 查看

  早上,考了一堂试,noip2011D2的题,只得了150 。。。。

  T1是一道水题,自己在草稿纸上画画就能推出来,要用到杨辉三角。

  T2有点扯淡。原题http://www.codevs.cn/problem/1138/

  我看数据非常大,本以为是高级数据结构,但自己不会写于是跑了个二分+暴力,想行到竟然50分,他们写的高级数据结构没分。 正解是 二分+前缀优化暴力  。在每次check时先跑一遍所有矿物求出前缀,再循环每个区间,用 (r)-(l-1) 即可。

  T3是一道贪心题,非常好的贪心题目。原题http://www.codevs.cn/problem/1139/

  首先呢,贪心策略肯定是在人多的时候用加速器。但用了加速器后到了下一个路口是否等人?如果等了,用了和没用一样的效果。我们可以预处理出每个站到下一个不用等人的站的位置,记录每个站的下车人数,用前缀和,减去就可以得到在某一阶段的车上人数。循环来寻找某个路上人最多且不用等的时候,ans减去人数即可,由此我们知道需要循环遍历k来消耗完所有的加速器。

  PS:不能一次消耗很多加速器,因为每次用完加速器后,车子需要等人的站要相对变化,所以一次只用一个加速器。

 

  然后,下午学习了数位dp。

  数位dp关键就是考虑限制,记忆化搜索,从高位到低位依次搜索,还是比较见到(比后缀数组好多了,至少我这么觉得)。  关键:把数看成一个串

  下面放两道晚上写的题。

  1.含有13且被13整除的数有多少个

  裸题,加一个限制表明到当前这位是否已经出现13,再加一个限制表明到此位的mod

CODE:

 

/*
注释  :
42 bit[++len]=n%10;  46行应为for(int i=1;i<=len;i++)ans+=dfs(len,i,0,1);
26行应为  if(pos==-1)......
为什么??我也想问为什么  :

数组大小  别人 len++比自己少用一位

*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define inf 2147483647
using namespace std;
int bit[20];
long long dp[20][20][2005];
long long read(){
char c;int f=1;long long x=0;c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
return f*x;
}

long long dfs(int pos,int o,int sum,int limit){
if(pos==0)return sum==0;
if(sum<0)return 0;
if(!limit&&dp[pos][o][sum]!=-1)return dp[pos][o][sum];
int num=limit?bit[pos]:9;long long ans=0;
for(int i=0;i<=num;i++){
int next=sum;
next+=(pos-o)*i;
ans+=dfs(pos-1,o,next,limit&&i==num);
}
if(!limit)dp[pos][o][sum]=ans;
return ans;
}

long long solve(long long n){
int len=0;
while(n){
bit[++len]=n%10;
n/=10;
}
long long ans=0;
for(int i=1;i<=len;i++)ans+=dfs(len,i,0,1);
return ans-len+1;
}

int main(){
int T;
scanf("%d",&T);
memset(dp,-1,sizeof(dp));
while(T--){
long long l,r;
cin>>l>>r;
cout<<solve(r)-solve(l-1)<<endl;
}
return 0;
}
View Code

 

  啊!明天出去考试,考完就要学常规了,好tm恐惧啊。。。。

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: