hdu1021

给n,看费波纳列数能否被3整除

算是找规律吧,以后碰到这种题就打打表找找规律吧

#include <stdio.h>
int main(void)
{
int n;
while(scanf("%d", &n) != EOF)
{
if(n%== || n%==)
printf("yes\n");
else
printf("no\n");
}
return ;
}

hdu1022 栈的简单利用吧

给两个队列  看第一个队列是否可以用第二个队列的方式出去

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<stack>
using namespace std;
int main()
{
char s1[],s2[];
int n,j,k,f[];
stack<char>s;
while(cin>>n>>s1>>s2)
{
while(!s.empty())
s.pop(); memset(f,-,sizeof(f));
j=k=;
for(int i=;i<n;i++)
{
s.push(s1[i]);
f[k++]=;
while(!s.empty()&&s.top()==s2[j])
{
f[k++]=;
s.pop();
j++;
}
}
if(j==n)
{
cout<<"Yes."<<endl;
for(int i=;i<k;i++)
{
if(f[i]) cout<<"in"<<endl;
else cout<<"out"<<endl;
}
}
else cout<<"No."<<endl;
printf("FINISH\n");
}
return ;
}

hdu1023  什么什么卡特兰数。。。

这个还是卡特兰数+大数

https://blog.csdn.net/wu_tongtong/article/details/78161211

卡特兰数规律

令h(0)=1,h(1)=1,catalan数满足递推式 [2
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)*h(0) (n>=2)
h(n)=C(2n,n)/(n+1) (n=0,1,2,...)
#include<iostream>
#include<cstdio>
#include<cstring> using namespace std; int a[][]; //大数卡特兰数
int b[]; //卡特兰数的长度 void Catalan(){ //求卡特兰数
int i,j,len,carry,tmp;
a[][]=b[]=;
len=;
for(i=;i<=;i++){
for(j=;j<len;j++) //乘法
a[i][j]=a[i-][j]*(*i-);
carry=;
for(j=;j<len;j++){ //处理相乘结果
tmp=carry+a[i][j];
a[i][j]=tmp%;
carry=tmp/;
}
while(carry){ //进位处理
a[i][len++]=carry%;
carry/=;
}
//carry=0;
for(j=len-;j>=;j--){ //除法
tmp=carry*+a[i][j];
a[i][j]=tmp/(i+);
carry=tmp%(i+);
}
while(!a[i][len-]) //高位零处理
len--;
b[i]=len;
}
} int main(){ //freopen("input.txt","r",stdin); int n;
Catalan();
while(~scanf("%d",&n)){
for(int i=b[n]-;i>=;i--)
printf("%d",a[n][i]);
printf("\n");
}
return ;
}

hdu1024

又是dp。。。难得一匹,给n个数,你可以划分m个区间,求这些区间的最大值。二维的dp还不行,还要利用滚动数组降维

https://blog.csdn.net/pmt123456/article/details/52695470 这个解释还是比较好的

这题给我的启发:dp找方程时,一定要弄清楚会有几个不同的状态,可以事先手动模拟一下。

比如这题,先是有两个变化的数n和m,那么我就想dp[i][j],有i个区间j个数的最大值。对于ai来数,我就要想到,ai会和哪些dp(上一个)联系起来

这个数我可以把它当成一个新区间的开始(2) 或者是它不是新区间的开始点(1)

①(x1,y1),(x2,y2)...(xi,yi,num[j])

②(x1,y1),(x2,y2)...(xi-1,yi-1),...,(num[j]),其中yi-1是第k个数字

故:d[i][j]=max(  d[i][j-1]   ,  d[i-1][k]   )+num[j],其中k=i-1,i,...,j-1

优化方法

注意到,d[i][*]只和d[i][*],d[i-1][*]有关,即当前状态只与前一状态有关,可以用滚动数组完成

d[t][j]=max(d[t][j-1],d[1-t][k])+num[j],其中k=i-1,i,...,j-1,t=1

其中只需要记录两个状态,当前状态t=1,上一状态t=0

空间优化了但时间没有优化

考虑我们也不需要j-1之前的最大和具体发生在k位置,只需要在j-1处记录最大和即可,用pre[j-1]记录即可

pre[j-1],不包括num[j-1]的j-1之前的最大和

则d[t][j]=max(d[t][j-1],pre[j-1])+num[j]

此时可以看见,t这一维也可以去掉了

即最终的状态转移为

d[j]=max(d[j-1],pre[j-1])+num[j]

#include <iostream>
#include<cstdio>
#include<memory.h>
using namespace std;
const int maxn=;
const int maxm=;
const int inf=0x7ffffff;
//int d[maxm][maxn];
int num[maxn];
int d[maxn];
int pre[maxn];
/*
int main()
{
freopen("in.txt","r",stdin);
int m,n,tmp;
while(cin>>m>>n){
for(int i=1;i<=n;++i){
cin>>num[i];
}
//dp[i][j],第j个人放在第i组时的最大值(1<=i<=j<=n,1<=i<=m)
for(int i=0;i<=n;++i){
d[0][i]=0;
d[i][0]=0;
}
for(int i=1;i<=m;++i){
for(int j=i;j<=n;++j){
tmp=-inf;
for(int k=i-1;k<=j-1;++k){
if(tmp<d[i-1][k])tmp=d[i-1][k];
}
d[i][j]=max(d[i][j-1],tmp)+num[j];
}
}
cout<<d[m][n]<<endl;
}
return 0;
}
*/
int main()
{
//freopen("in.txt","r",stdin);
int m,n,tmp;
while(cin>>m>>n){
int tmp;
for(int i=;i<=n;++i){
cin>>num[i];
}
//dp[i][j],第j个人放在第i组时的最大值(1<=i<=j<=n,1<=i<=m)
memset(d,,sizeof(d));
memset(pre,,sizeof(pre));
for(int i=;i<=m;++i){
tmp=-inf;
for(int j=i;j<=n;++j){
d[j]=max(d[j-],pre[j-])+num[j];
pre[j-]=tmp;
tmp=max(tmp,d[j]);
}
}
cout<<tmp<<endl;
} return ;
}

hdu1025 最长上升子序列+二分优化??????

https://blog.csdn.net/u011721440/article/details/21107113

现在,我们仔细考虑计算dp[t]时的情况。假设有两个元素a[x]和a[y],满足

(1)x < y < t

(2)a[x] < a[y] < a[t]

(3)dp[x] = dp[y]

此时,选择dp[x]和选择dp[y]都可以得到同样的dp[t]值,那么,在最长上升子序列的这个位置中,应该选择a[x]还是应该选择a[y]呢?

很明显,选择a[x]比选择a[y]要好。因为由于条件(2),在a[x+1] ... a[t-1]这一段中,如果存在a[z],a[x] < a[z] < a[y],则与选择a[y]相比,将会得到更长的上升子序列。

再根据条件(3),我们会得到一个启示:根据dp[]的值进行分类。对于dp[]的每一个取值k,我们只需要保留满足dp[t] = k的所有a[t]中的最小值。设D[k]记录这个值,即D[k] = min{a[t]} (dp[t] = k)。

注意到D[]的两个特点:

(1) D[k]的值是在整个计算过程中是单调不上升的。

(2) D[]的值是有序的,即D[1] < D[2] < D[3] < ... < D[n]。

利用D[],我们可以得到另外一种计算最长上升子序列长度的方法。设当前已经求出的最长上升子序列长度为len。先判断a[t]与D[len]。若a [t] > D[len],则将a[t]接在D[len]后将得到一个更长的上升子序列,len = len + 1, D[len] = a [t];否则,在D[1]..D[len]中,找到最大的j,满足D[j] < a[t]。令k = j + 1,则有a [t] <= D[k],将a[t]接在D[j]后将得到一个更长的上升子序列,更新D[k] = a[t]。最后,len即为所要求的最长上 升子序列的长度。

在上述算法中,若使用朴素的顺序查找在D[1]..D[len]查找,由于共有O(n)个元素需要计算,每次计算时的复杂度是O(n),则整个算法的时间复杂度为O(n^2),与原来的算法相比没有任何进步。但是由于D[]的特点(2),我们在D[]中查找时,可以使用二分查找高效地完成,则整个算法的时间复杂度下降为O(nlogn),有了非常显著的提高。需要注意的是,D[]在算法结束后记录的并不是一个符合题意的最长上升子序列!

#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
int a[],dp[];
int main()
{
int n,x,y,count=;
while(~scanf("%d",&n))
{
for(int i=; i<=n; i++)
{
scanf("%d%d",&x,&y);
a[x]=y;
}
int len=;
dp[]=a[];
for(int i=; i<=n; i++)
{
int l=;
int r=len;
while(l<=r)
{
int mid=(l+r)/;
if(dp[mid]>=a[i])
r=mid-;
else
l=mid+;
}
dp[l]=a[i];
if(l>len)
len++;
}
printf("Case %d:\nMy king, at most %d road",count++,len);
if(len!=) printf("s");
printf(" can be built.\n\n");
}
}

hdu1026广搜+优先队列+递归打印路径

#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 #include<iostream>
#include<algorithm>
#include<functional>
#include<vector>
#include<queue> using namespace std; int n, m;
int dir[][] = { { , },{ ,- },{ , },{ -, } };
struct Node
{
int time;
int x, y;
int prex, prey;
char ch; bool operator>(const Node & node) const
{
return time > node.time;
} }node[][]; bool BFS()
{
int i;
int mx, my;
Node cur;
priority_queue<Node, vector<Node>, greater<Node> > pq; node[][].time = ;
pq.push(node[][]); while (!pq.empty())
{
cur = pq.top();
pq.pop();
if (cur.x == n - && cur.y == m - )
return true;
for (i = ; i < ; i++)
{
mx = cur.x + dir[i][];
my = cur.y + dir[i][];
if (mx >= && mx < n&&my >= && my < m)
{
if (node[mx][my].ch == '.'&&node[mx][my].time > cur.time + )
{
node[mx][my].time = cur.time + ;
node[mx][my].prex = cur.x;
node[mx][my].prey = cur.y;
pq.push(node[mx][my]);
}
else if (node[mx][my].ch >= ''&&node[mx][my].ch <= ''&&node[mx][my].time > cur.time + node[mx][my].ch - ''+)//注意这里加1
{
node[mx][my].time = cur.time + node[mx][my].ch - '' + ;//注意这里加1
node[mx][my].prex = cur.x;
node[mx][my].prey = cur.y;
pq.push(node[mx][my]);
}
}
}
} return false;
} void printPath(int x, int y)
{
if (x == && y == )
return; int prex = node[x][y].prex;
int prey = node[x][y].prey; printPath(prex, prey); int prelength = node[prex][prey].time;
int length = node[x][y].time;
printf("%ds:(%d,%d)->(%d,%d)\n", prelength + , prex, prey, x, y);
for (int i = prelength + ; i <= length; i++)
{
printf("%ds:FIGHT AT (%d,%d)\n", i, x, y);
}
} int main()
{ int i, j;
while (~scanf("%d%d", &n, &m))
{
for (i = ; i < n; i++)
{
getchar();
for (j = ; j < m; j++)
{
scanf("%c", &node[i][j].ch);
node[i][j].time = INT_MAX;
node[i][j].x = i;
node[i][j].y = j;
}
} bool state = BFS();
if (!state)
{
printf("God please help our poor hero.\n");
printf("FINISH\n");
continue;
}
printf("It takes %d seconds to reach the target position, let me show you the way.\n", node[n - ][m - ].time);
printPath(n - , m - );
printf("FINISH\n");
} return ;
}

hdu1027 n个数字典序排序的第m个排序    全排列也有函数。。。。。。。。。。。

next_permutation(后一个)和prev_permutation(前一个)函数

依照STL文档的描写叙述,next_permutation函数将按字母表顺序生成给定序列的下一个较大的序列。直到整个序列为减序为止。prev_permutation函数与之相反。是生成给定序列的上一个较小的序列。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
#define N 1047
int num[N];
int main()
{
int n , m , i ,k;
while(~scanf("%d%d",&n,&m))
{
memset(num,,sizeof(num));
for(i = ; i < n ; i++)
{
num[i] = i+;
}
for(i = ; i < m ; i++)
{
next_permutation(num,num+n);
}
for(i = ; i < n- ; i++)
printf("%d ",num[i]);
printf("%d\n",num[n-]);
}
return ;
}

hdu1028  母函数和dp  都是大boss。。。

看了好久模板。。也看得不是太懂,xxde  记住不得了  https://blog.csdn.net/xiaofei_it/article/details/17042651

/*a[0]=1;
int last=0; for(int i=0;i<n;i++)
{
int last2=min(last+n[i]*v[i],p);
memset(b,0,sizeof(int)*(last2+1));
for(int j=n1[i];j<=n2[i]&&j*v[i]<=last2;j++)
{
for(int k=0;k<=last&&k+j*v[i]<=last2;k++)
b[k+j*v[i]]+=a[k];
}
memcpy(a,b,sizeof(int)*(last2+1));
last=last2;
}*/
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
int v[],num[];
int a[],b[],last,last2;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=;i<=n;i++)
v[i]=i,num[i]=n/i;
//for(int i=1;i<=n;i++)
//cout<<v[i]<<num[i];
a[]=;
last=;
for(int i=;i<n;i++)
{
int last2=min(last+num[i]*v[i],n);
memset(b,,sizeof(int)*(last2+));
for(int j=;j<=num[i]&&j*v[i]<=n;j++)
{
for(int k=;k<=last&&k+j*v[i]<=last2;k++)
b[k+j*v[i]]+=a[k];
}
memcpy(a,b,sizeof(int)*(last2+));
last=last2;
}
cout<<a[n]+<<endl;
}
}

又瞅了瞅dp版的

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int main()
{
int n;
int dp[][];//第一个数表示要组成的数,第二个数为组合数中最大的一个
int i,l;
memset(dp,,sizeof(dp));
dp[][]=;
for(int i=;i<=;i++)
{
dp[i][]=;
dp[][i]=;
}
for(int i=;i<=;i++)
{
for(int j=;j<=;j++)
{
if(i>j) d[i][j]=d[i-j][j]+d[i][j-];
else if(i==j) d[i][j]=+d[i][j-];
else d[i][j]=d[i][i];
}
}
while(scanf("%d",&n)!=EOF)
{
cout<<dp[n][n]<<endl;
}
return ;
}

想了半天自己对压缩又有点理解了,就是想办法把j或者i通过循环的方式来降维

比如dp[10][7]=dp[3][7]+dp[10][6]    注意dp[3][7]=dp[3][6];所以最终方程为

for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= n; j++)
{
dp[j] += dp[j - i];
}
}

#include <iostream>
using namespace std; const int M = + ; int dp[M]; int main()
{
int n;
while (~scanf("%d", &n))
{
memset(dp, , sizeof(dp));
dp[] = ;
for (int i = ; i <= ; i++)
{
for (int j = ; j <= n; j++)
{
dp[j] += dp[j - i];
}
} printf("%d\n", dp[n]);
}
return ;
}

hdu1029水过

hdu1030  规律题https://www.cnblogs.com/ACMan/archive/2012/05/30/2526798.html

hdu刷题2的更多相关文章

  1. 教你用python写:HDU刷题神器

    声明:本文以学习为目的,请不要影响他人正常判题 HDU刷题神器,早已被前辈们做出来了,不过没有见过用python写的.大一的时候见识了学长写这个,当时还是一脸懵逼,只知道这玩意儿好屌-.时隔一年,决定 ...

  2. hdu 刷题记录

    1007 最近点对问题,采用分治法策略搞定 #include<iostream> #include<cmath> #include<algorithm> using ...

  3. hdu刷题1

    1002  大数加法 #include<iostream> #include<cstring> using namespace std; int main() { ],b[]; ...

  4. HDU 自动刷题机 Auto AC (轻轻松松进入HDU首页)

    前言: 在写这篇文章之前,首先感谢给我思路以及帮助过我的学长们 以下4篇博客都是学长原创,其中有很多有用的,值得学习的东西,希望能够帮到大家! 1.手把手教你用C++ 写ACM自动刷题神器(冲入HDU ...

  5. 手把手教你用C++ 写ACM自动刷题神器(冲入HDU首页)

    转载注明原地址:http://blog.csdn.net/nk_test/article/details/49497017 少年,作为苦练ACM,通宵刷题的你 是不是想着有一天能够荣登各大OJ榜首,俯 ...

  6. 【刷题】HDU 2222 Keywords Search

    Problem Description In the modern time, Search engine came into the life of everybody like Google, B ...

  7. NOIp2018停课刷题记录

    Preface 老叶说了高中停课但是初中不停的消息后我就为争取民主献出一份力量 其实就是和老师申请了下让我们HW的三个人听课结果真停了 那么还是珍惜这次机会好好提升下自己吧不然就\(AFO\)了 Li ...

  8. LeetCode刷题系列

    LeetCode 我们工作面试和提高自身数据结构和算法能力的时候往往需要刷刷题,我选择LeetCode是通过一个留学论坛了解的.专业,覆盖语种全面. 提前说说刷题的心得: 尽量手写代码,少使用IDE的 ...

  9. ife任务刷题总结(一)-css reset与清除浮动

    本文同时发布于本人的个人网站www.yaoxiaowen.com 百度创办的前端技术学院,是一个面向大学生的前端技术学习平台.虽然只有大学生才有资格报名,提交代码进行比赛排名.但是这并不妨碍我们这些初 ...

随机推荐

  1. win7利用winSCP上传文件到ubuntu server

    1.为ubuntu server设置root密码: sudo passwd root 先设密码在登录 2. su root进入root账户: 3.安装SSH:sudo apt-get install ...

  2. 在js中获取request域中的内容

    1.可以使用小脚本<%%>实现: var pro_id=<%request.getPro_id()%>; 2.使用隐藏域实现: <input type="hid ...

  3. 微信网页授权-公众号支付(获取openid、用户信息等)

    名词解释: openid 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID 业务功能描述:实现H5页面可以在微信浏览器里面进行微信支付,所以需要 ...

  4. 三层架构,Struts2,SpringMVC实现原理图

    三层架构,Struts2,SpringMVC实现原理图 三层架构实现原理 Struts2实现原理 SpringMVC实现原理

  5. LogViewer超大文本浏览工具

    官方下载 LogViewer 是一款简单好用的log日志文件查看工具.您想要查看log日志吗?那么不妨来看看这款LogViewer .该款工具可以在短短数秒内打开上G的LOG文件,支持高亮某行文字(例 ...

  6. 前端的字符串时间如何自动转换为后端Java的Date属性,介绍springMVC中如何解决时间转换问题

    平常在开发过程中,前端选择时间一般都要使用时间选择插件,但是这种插件选出来的时间都是字符串类型,我们该怎么转换为后端的Date呢?/? 前端效果如下(笔者用的是layDate5.0插件): 修改前的后 ...

  7. Oracle之基础操作

    sqlplus常用命令: 进入sqlplus模式:sqlplus /nolog 管理员登录: conn / as sysdba 登录本机的数据库 conn sys/123456 as sysdba 普 ...

  8. Hive(9)-自定义函数

    一. 自定义函数分类 当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数. 根据用户自定义函数类别分为以下三种: 1. UDF(User-Defined-Functi ...

  9. scala 获取当前时间的两种方式

    在编写程序时,有时需要获取当前时间,这在记录异常信息.获取程序运行耗时很有用处 方式一: val time1=System.currentTimeMillis() 这种方式获取的是程序运行到此的毫秒数 ...

  10. rails应用中各数据平台的对接

    1.mongo #Gemfile添加如下两个gem包gem 'mongoid', '~> 5.1.0' gem 'mongo', '~> 2.4’ @client = Mongo::Cli ...