目录
P1255 数楼梯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1255
P1002 [NOIP2002 普及组] 过河卒 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P1044 [NOIP2003 普及组] 栈 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1044
P1028 [NOIP2001 普及组] 数的计算 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1028
P1928 外星密码 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1928
大任务 分成 小任务
动态规划 Dynamic programming,简称DP
分治策略
例如:
for(int i=3 ;i <=N;i++)
f[i] = f[i-2]+f[i-1];
f[N].print();
return 0;
P1255 数楼梯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1255
忘了一道最典的题,这是后加的,建议从第二题开始(
w,随手一写RE,WA了(60分,正好及格,也算AC)
错误代码
#include <bits/stdc++.h>
using namespace std;
int n;
long long dp[5000]={1,1,2};
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin>>n;
for(int i=3;i<=n;i++){ //<=n 怎么又忘了
for(int j=i-2;j<i;j++)
dp[i]+=dp[j];
}
cout<<dp[n];
return 0;
}
高精度 打扰了 第7个测试点是500
输出:225591516161936330872512695036072072046011324913758190588638866418474627738686883405015987052796968498626 爆
#include <bits/stdc++.h>
using namespace std;
int n,f[5010][5010],len;
void jiafa(int k)//高精加法
{
for(int i=1; i<=len; i++)//两数相加
f[k][i]=f[k-1][i]+f[k-2][i];
for(int i=1; i<=len; i++)//进位
if(f[k][i]>=10)
{
f[k][i+1]+=f[k][i]/10;
f[k][i]%=10;
if(f[k][len+1]>0)len++;
}
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin>>n;
len=1;
f[1][1]=1;//预处理
f[2][1]=2;//预处理
for(int i=3; i<=n; i++)//开始计算
jiafa(i);
for(int i=len; i>=1; i--)//输出
cout<<f[n][i];
return 0;
}
1e8 没TLE(不对,我为何如此惧怕TLE)
P1002 [NOIP2002 普及组] 过河卒 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P155
假设先没有🐎
寻找初始条件 :向右 或 向左移动
寻找递推式
f[1,1]=f[0,1]+f[1,0]; //0,0到1,1的方法总数 --f[1,1]
f[i,j]=f[i-1,j]+f[i,j-1]; //推
有了递推式,有了初始条件,就可以求出完整的f数组的值了。
特别求出马控制的点。
#include <bits/stdc++.h>
using namespace std;
long long f[22][22];
int ctrl[22][22],n,m,hx,hy;
int dict[9][2]={{0,0},{-1,-2},{1,-2},{-1,2},{1,2},{-2,-1},{-2,1},{2,-1},{2,1}};//马点
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin>>n>>m>>hx>>hy; //输入要到的点(n,m) &马(hx,hy)
for(int i=0;i<9;i++)
if(hx+dict[i][0]>=0&&hx+dict[i][0]<=n
&&hy+dict[i][1]>=0&&hy+dict[i][1]<=m)// 如果不在地图内 忽略
ctrl[hx+dict[i][0]][hy+dict[i][1]] =1;//马控制的具体点
f[0][0]=1-ctrl[0][0]; //起始点 如果被马控制 直接GG 甚至可加
/*
if(!f[0][0]) {cout<<0; return 0;}
*/
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++){
if(ctrl[i][j]) continue; //若为控制点 跳过 默认为0
if(i!=0) f[i][j]+=f[i-1][j]; //x
if(j!=0) f[i][j]+=f[i][j-1]; //y
}
cout<<f[n][m]; //输出, 没想到我也有烦死了的一天
return 0;
}
实在看不了我的代码屎山可以看官方(借鉴
P1044 [NOIP2003 普及组] 栈 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1044
一共N个球,假设i个元素有h[i]出球方式 , 第k个小球 算前面的小球
递推式:h(n)= h(0)*h(n-1) + h(1)*h(n-2) +…+ h(n-1)*h(0) ( 看得像
#include <bits/stdc++.h>
using namespace std;
long long h[20]={1,1};
int n;
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin>>n;
//h[0]=1,h[1]=1; 改成上面了 h[20]={1,1}; 在声明时就能赋值...
for(int i=2;i<=n;i++) //<=n,取到n 只知道h[0],h[1] 循环求h[n]
for(int j=0;j<i;j++)
h[i] += h[j] *h[i-j-1]; //i-j-1
cout<<h[n]; //n==1时 本来有值,所以for循环pass也没问题
return 0;
}
P1028 [NOIP2001 普及组] 数的计算 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1028
简单
#include <bits/stdc++.h>
using namespace std;
int n;
long long h[1000]={1,1,2}; //大 占用的又不是我的空间
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin>>n;
for(int i=3;i<=n;i++){
for(int j=0;j<=i/2;j++)
//2层循环 把i/2 改成i 都不会TLE 耗得又不是我的算力(^U^)ノ
//(1000-3+1)*(1000-3) 连1e6都不够 一秒1e8(/▽\)
h[i]+=h[j];
}
cout<<h[n];
return 0;
}
参考代码都比我麻烦 --(超时?)
顺便复习一下memset
#include <iostream> #include <cstring> int main() { char str[10]; memset(str, 'A', sizeof(str) - 1); str[sizeof(str) - 1] = '\0'; std::cout << str << std::endl; return 0; }
输出结果为:
AAAAAAAAA
。(9个A)在这个例子中,memset(str, 'A', sizeof(str) - 1)
将字符数组str
的每个字节都设置为'A'
,然后在末尾添加了一个空字符'\0'
,以确保字符串的终止。需要注意的是,C++提供了更安全和类型友好的初始化和赋值方式,如使用构造函数、循环或
std::fill
等。因此,在C++中使用memset
应该谨慎,尤其是当处理非字符类型的数组时,以避免类型不匹配或对象构造/析构的问题。
P1928 外星密码 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1928
递归
#include <bits/stdc++.h>
using namespace std;
string expand(){
string s ="",X;
char c; int D;
while(cin>>c){
if(c =='['){ //[
cin>>D;
X= expand();
while(D--){
s+=X;
}
}
else if(c==']'){ //]
return s;
}
else s +=c;
}
return s;//循环结束,在无[]时候
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cout<<expand();
return 0;
}