​ 逼近法是一种很奇妙的算法,以为“逼近”这一种思想在很多的算法中都有体现。诸如:像我们的二分答案,不断地排除决策集合的一半以接近我们的最终答案;我们的树上倍增求 $ LCA $ 算法,一次次的减小我们跳的距离以确定祖先的准确位置;我们的模拟退火需要用一个温度,每次操作后这个温度一定会下降,逼近正确答案;再如我们大多数函数的收敛性,在多次计算后会趋向某一定值;还有我们DP的拼凑与试填的思想也有逼近的味道。

我们逼近的前提就在于我们是否可以在每一次操作后排除一些决策集合,并且是高效的排除。就像:银河系 -> 太阳系 -> 太阳系 -> 地球 -> 中国 -> 湖南 -> 长沙。还有我做出来的第一道逼近题:存在很多长度为 $ n $ 的有26个字母组成的字符串,我们将他们按字典序排序,现在给出序号或字符串,要求输出它对应的序号或字符串。这是一道傻逼题,我们可以试填第一个字母,然后它后面剩余的位置有很多种填法,我们看这么多填法是否大于我们的序号,然后我们从小到大填,这样可以确定第一个字母,紧接着可以推出第二个第三个.....然后就是答案。

虽然写的都是些浅显的东西,但如果这个思想和其他东西串联起来就不见得简单了。好了说白了就是来写题解的,不管这么多了。。。。。。。。。。。。。。。。。。。。




Poj 1037 A decorative fence

大致题意:我们要构建长度为 $ N $ 的排列,使得排列里的每一个元素同时大于或小于旁边两个数。可以预见这样的数很多,我们将这些排列按字典序排序,现在给出序号求对应的排列。



$ solution: $

就是我举的那个例子的一个变形,只不过多了一个限制:(每一个元素同时大于或小于旁边两个数)。这样我们只需要在逼近的时候特判第一个数是大于或小于第二个数(当然不能忘记我们DP第一维始终得是排列长度,这样才符合逼近思想),然后在逼近的同时维护大于和小于即可!



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set> #define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int using namespace std; ll m;
int t,n,l;
ll f[25][25][2];
bool use[25]; inline ll qr(){
register char ch; register bool sign=0; ll res=0;
while(!isdigit(ch=getchar())) if(ch=='-')sign=1;
while(isdigit(ch)) res=res*10+(ch^48),ch=getchar();
return sign?-res:res;
} int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
n=20; f[1][1][0]=f[1][1][1]=1;
for(rg i=2;i<=n;++i){
for(rg j=1;j<=i;++j){
for(rg k=1;k<j;++k)
f[i][j][1]+=f[i-1][k][0];
for(rg k=j;k<i;++k)
f[i][j][0]+=f[i-1][k][1];
}
} t=qr();
while(t--){
n=qr(); m=qr();
register bool k=0;
for(rg i=1;i<=n;++i) use[i]=0;
for(rg i=1;i<=n;++i){
if(f[n][i][1]>=m){
k=1; l=i; break;
} else m-=f[n][i][1];
if(f[n][i][0]>=m){
k=0; l=i; break;
} else m-=f[n][i][0];
}use[l]=1; printf("%d",l);
for(rg i=n-1;i>=1;--i){
k^=1; rg s=0;
for(rg j=1;j<=n;++j){
if(use[j])continue;; ++s;
if((!k&&j<l)||(k&&j>l)){
if(f[i][s][k]>=m){
l=j; break;
} else m-=f[i][s][k];
}
}printf(" %d",l); use[l]=1;
}puts("");
}
return 0;
}



Poj 3208 Apocalypse Someday

大致题意:我们规定所有含有连续三个数字6的自然数都是“神秘数”。我们将这些数按字典序排序(及时从小到大),现在给出序号,让你求出对应的“神秘数”。



$ solution: $

又是一道变形题,但这一次改的比较难了一点,因为它需要连续的三个六,这给我们的逼近带来了后效性,如果我们确定的上一个数是6,那么这次逼近里面,开头只带有两个数字6的数也会加如决策集合。所以我们DP维护数字长度为i,含有连续的j个六的数字有多少。然后在逼近时另取一个变量来存已经连续确定了几个六然后找准决策集合进行逼近!



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set> #define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int using namespace std; int t,n,m;
ll f[25][4]; inline int qr(){
register char ch; register bool sign=0; rg res=0;
while(!isdigit(ch=getchar())) if(ch=='-')sign=1;
while(isdigit(ch)) res=res*10+(ch^48),ch=getchar();
return sign?-res:res;
} int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
f[0][0]=1;
for(rg i=0;i<20;++i){
for(rg j=0;j<3;++j){
f[i+1][j+1]+=f[i][j];
f[i+1][0]+=f[i][j]*9;
}f[i+1][3]+=f[i][3]*10;
} t=qr();
while(t--){
n=qr(); rg k=3;
for(m=3;f[m][3]<n;++m);
for(rg i=m;i>=1;--i){
for(rg j=0;j<=9;++j){
ll tot=f[i-1][3];
if(j==6||!k)
for(rg o=max(k-(j==6),0);o<3;++o)
tot+=f[i-1][o];
if(tot<n)n-=tot;
else{
if(k)j==6?--k:k=3;
printf("%d",j);
break;
}
}
}puts("");
}
return 0;
}

逼近法(例 poj3208、poj1037)的更多相关文章

  1. Leetcode 11. Container With Most Water(逼近法)

    11. Container With Most Water Medium Given n non-negative integers a1, a2, ..., an , where each repr ...

  2. 最新IP地址数据库 二分逼近&二分查找 高效解析800万大数据之区域分布

    最新IP地址数据库  来自 qqzeng.com 利用二分逼近法(bisection method) ,每秒300多万, 比较高效! 原来的顺序查找算法 效率比较低 readonly string i ...

  3. POJ 3889 Fractal Streets(逼近模拟)

    $ POJ~3889~Fractal~Streets $(模拟) $ solution: $ 这是一道淳朴的模拟题,最近发现这种题目总是可以用逼近法,就再来练练手吧. 首先对于每个编号我们可以用逼近法 ...

  4. openjudge-膨胀的木棍

    http://noi.openjudge.cn/ch0111/09/ 总时间限制: 1000ms  内存限制: 65536kB 描述 当长度为L的一根细木棍的温度升高n度,它会膨胀到新的长度L'=(1 ...

  5. 分类器的评价指标-ROC&AUC

    ROC 曲线:接收者操作特征曲线(receiver operating characteristic curve),是反映敏感性和特异性连续变量的综合指标,roc 曲线上每个点反映着对同一信号刺激的感 ...

  6. POJ 1905 Expanding Rods 木棍膨胀

    描述 当长度为L的一根细木棍的温度升高n度,它会膨胀到新的长度L'=(1+n*C)*L,其中C是热膨胀系数. 当一根细木棍被嵌在两堵墙之间被加热,它将膨胀形成弓形的弧,而这个弓形的弦恰好是未加热前木棍 ...

  7. P2750 贰五语言Two Five USACO5.5 记忆化搜索

    正解:记搜+逼近 解题报告: 神仙题预警,,, 我真滴觉得还是挺难的了,,, 大概说下思路趴QAQ 首先我们要知道逼近法是什么! 逼近法,有点像二分的思路,以这题为例举个eg 假如它给了个数字k.我们 ...

  8. NOI2001 方程的解数

    1735 方程的解数 http://codevs.cn/problem/1735/ 2001年NOI全国竞赛  时间限制: 5 s  空间限制: 64000 KB     题目描述 Descripti ...

  9. 转载论文关于fir滤波器的fpga实现

    摘 要 本文讨论的FIR滤波器因其具有严格的线性相位特性而得到广泛的应用.在工程实践中,往往要求信号处理具有实时性和灵活性,本论文研究FIR的FPGA解决方案正体现了电子系统的微型化和单片化. 本论文 ...

随机推荐

  1. HackerRank# Hexagonal Grid

    原题地址 铺瓷砖的变种,做法也是类似 假设地板长下面这样,灰色的是无法填充的空洞,初始时可以把N块之外的地板填充成灰色的,便于边界处理 假设现在从后向前已经处理完了一部分,绿色的砖块代表已经遍历过了, ...

  2. [luoguP3413] SAC#1 - 萌数(数位DP)

    传送门 gtm的数位dp! 看到好多题解,都是记忆化搜索,好像非常方便啊,但是我还是用递推好了,毕竟还是有些类似数位dp的题用递推的思路,记忆化做不了,现在多培养一下思路 首先这道题, 只看长度大于等 ...

  3. noip普及组考纲+样题合集——初级篇(OIer必看)

    很明显我是想发提高组合集的.普及组考纲……用发么. 当然如果你想看的话也可以,就一点点: 递归.排序…… 很明显上面那都不是重点.普及组只要掌握搜索.二分.单调队列.数学.随机化等等,一等奖没问题的, ...

  4. Codeforces963D. Frequency of String

    $n \leq 100000$的一文本串,给$m \leq 100000$个询问,每次问一小串在文本串的哪一个最短的子串里出现指定次数.注意,询问串互不相同,且总长度$\leq 100000$. 比赛 ...

  5. PatentTips - GPU Support for Blending

    Graphics processing units (GPUs) are specialized hardware units used to render 2-dimensional (2-D) a ...

  6. msp430项目编程34

    msp430中项目---flash编程34 1.电路工作原理 2.代码(显示部分) 3.代码(功能实现) 4.项目总结

  7. Xcode6 pch文件

    XCode6里, 默认是没有pch文件的,如果我们想使用pch文件,需要手动添加,添加步骤如下 1.在XCode6中是么有pch文件的,如下图     2.创建pch文件     3.配置pch文件 ...

  8. centos 7 配置多个IP地址

    centos 7 配置多个IP地址 #打开网络配置文件 cd /etc/sysconfig/network-scripts/ vim ifcfg-eno167 找到IPADDR的位置,在下面再增加需要 ...

  9. WEB学习-CSS盒模型

    盒子的区域 一个盒子中主要的属性就5个:width.height.padding.border.margin. width是“宽度”的意思,CSS中width指的是内容的宽度,而不是盒子的宽度. he ...

  10. git(一):了解、学习、安装git

    自述 一直到今天才真正的去了解学习使用git,看<git权威指南>这本书的第一篇,忽然有很多共鸣,比如在大学开始编程的时候,总是把写的所有demo和项目保存在U盘里,内存不够用就改为移动硬 ...