首先谈谈C++ STL(Standard Template Library)中常用几种数据类型
1. list:双向链表 、基本等同数组 #include
2.vector:向量、基本等同个数组、和list区别在于存储空间连续 #include
3.queue: 队列、先进先出链表 #include
4.stack :栈、后进先出链表 #include
5.priority_queue:优先队列、排好序的队列 #include
6.set:集合、排好序的去重的数组 #include
7.map:python中的字典,自动根据关键字排好序 #include
8.其他..... 待了解
参考博客:
c++STL容器(map,set,vector,stack,queue)
C++list的使用总结及常用list操作
较常用的是vector、set和map,这些再和结构体组合起来用,美滋滋。自己实验了一下vector实现图邻接链表,map的基本操作
#include
#include
#include
效果如下:
进入正题
-------------------------------------------------------------我是分割线-----------------------------------------------------------------
递归:定义:函数自己调用自己。看完感受:啥玩意?
求阶乘那种简单问题看了等于没看。变换一下又蒙了。先看个题
这个题递归、递推都能实现。
题解:我要走到第n个台阶,要么从n-1走一步到,或者从n-2跨两阶到,。。。。从n-k阶跨k个台阶到。
也就是说走到n的方案数 S(n)= S(n-1)+ S(n-1)+.....+ S(n-k)(此处需要理解)
这么理解:
假设k=2,当n=1的时候可以从第0个台阶走1步 1种方案。
依次递推:n=2 从0走2步和从1走1步; S(2) = S(1)+S(0) = 1+1 =2;
n=3 从1走2步和从2走1步; S(3) = S(2)+S(1) = 2+1 =3;
。。。。。。。。。。。。。
递归代码就可以这么写:
#include
using namespace std;
int n,k;
int digui (int n){
if(n==0) return 1;
int sum=0;
for(int i=1;i<=k;i++)
{
if(n-i<0) break;
sum=(sum + digui(n-i))%100003;//此处为上面推导的公式
}
return sum%100003;
}
int main(){
cin>>n>>k;
int sum = digui(n);
cout<
恭喜:20分到手! 4804ms,已经很仁慈了
我感觉自己被骗了,说好的递归呢??
仔细想想,中间好像存在很多重复计算的过程。
比如n = 10, k=3;
n = 10 时,我需要递归 n=9,n=8,n=7
n = 9 时,我需要递归 n=8,n=7,n=6
n = 8 时,我需要递归 n=7,n=6,n=5
.。。。。。。。。。。
太多重复了!!!!!
我能不能只算一次呢? 状态数组说:没问题啊
思路很简单:每次算之后我把结果保存起来,下次到了先看一下算没算过,算过的话就直接取结果赶紧回家吧。
#include//万能库
using namespace std;
int n,k;
int s[100010];
int digui (int n){
if(n==0) return 1;
if(s[n]) return s[n];//算过了,给你数据,赶紧回家吧
int sum=0;
for(int i=1;i<=k;i++)
{
if(n-i<0) break;
s[n]=(s[n] + digui(n-i))%100003;
}
return s[n]%100003;
}
int main(){
cin>>n>>k;
int sum = digui(n);
cout<
大神看了一下,你这个竟然过了?? 10^4 * 10^3,很容易超啊
偷偷告诉你,时间可以降到 10^4,没错,一重循环就够了!
递推闪亮登场~
思想很简单:用一个变量保存前n-k到n的和,然后从前往后,每加一个数我就踢掉前面一个。
比如 i从 n-2到n-1,踢掉S(n-2-k),加上S(n-1),这样保证永远是n到n-k,k个结果之和。
有一篇通熟易懂的文章:漫画:什么是动态规划?
#include
using namespace std;
int n,k;
int dp[100010];
int main()
{
int n,k,i,j;
cin>>n>>k;
//for(i=1;i<=k;i++)
dp[0]=1;
int sum=dp[0];
for(i=1;i<=n;i++)
{
if(i
总结一下递推和递归:
递归:从后往前找解,也就是循环的另外一种实现手段,很暴力,当问题没法确定循环轮数或次数时考虑用递归。
递推:从前往后推导,跟核心公式跟递归一样,只不过保存每一次结果,时间一般比递归快,典型空间换时间。
其实递推和递归都是将问题分解为每一个子问题
基本就思考三个点:结束条件、每一次递归要解决的问题、每一步递归的意义
重点要理解递归执行的全部过程。