补一补基础题
P1028 [NOIP2001 普及组] 数的计算
题目描述
我们要求找出具有下列性质数的个数(包含输入的正整数 nnn)。
先输入一个正整数 nnn(n≤1000n \le 1000n≤1000),然后对此正整数按照如下方法进行处理:
不作任何处理;
在它的左边加上一个正整数,但该正整数不能超过原数的一半;
加上数后,继续按此规则进行处理,直到不能再加正整数为止。
输入格式
111 个正整数 nnn(n≤1000n \le 1000n≤1000)
输出格式
111 个整数,表示具有该性质数的个数。
输入输出样例
输入
6
输出
6
#include<iostream>
using namespace std;
int main()
{
int n,cnt=1,f[1000];
f[0]=f[1]=1;
cin>>n;
for(int i=2;i<=n;i++)
{
if(i%2==0)
{
f[i]=f[i-1]+f[i/2];
}
else f[i]=f[i-1];
}
cout<<f[n]<<endl;
}
感觉学了这个对动态规划会有更深层次的了解,哎,基础很重要呀,感觉要把基础打牢固了,其实一些比赛就是比谁做的更快,掌握的更牢固呀。
P1464 Function
#include <cstdio>
#define LL long long
LL dp[25][25][25];
LL w(LL a, LL b, LL c)
{
if(a <= 0 || b <= 0 || c <= 0) return 1;//两个特判,题意里都有的。
if(a > 20 || b > 20 || c > 20) return w(20, 20, 20);
if(a <b && b < c)//情况一,每一个没有储存过的“w”值全部储存,如果有就直接调用。
{
if(dp[a][b][c-1] == 0)
{
dp[a][b][c-1] = w(a, b, c-1);
}
if(dp[a][b-1][c-1] == 0)
{
dp[a][b-1][c-1] = w(a, b-1 ,c-1);
}
if(dp[a][b-1][c] == 0)
{
dp[a][b-1][c] = w(a, b-1, c);
}
dp[a][b][c] = dp[a][b][c-1] + dp[a][b-1][c-1] - dp[a][b-1][c];
}
else//同上
{
if(dp[a-1][b][c] == 0)
{
dp[a-1][b][c] = w(a-1, b, c);
}
if(dp[a-1][b-1][c] == 0)
{
dp[a-1][b-1][c] = w(a-1, b-1 ,c);
}
if(dp[a-1][b][c-1] == 0)
{
dp[a-1][b][c-1] = w(a-1, b, c-1);
}
if(dp[a-1][b-1][c-1] == 0)
{
dp[a-1][b-1][c-1] = w(a-1, b-1, c-1);
}
dp[a][b][c] = dp[a-1][b][c] + dp[a-1][b][c-1] + dp[a-1][b-1][c] - dp[a-1][b-1][c-1];
}
return dp[a][b][c];
}
int main()
{
LL a, b, c;
while(scanf("%lld%lld%lld", &a, &b, &c))//无限输入,直到“-1 -1 -1”
{
if(a == -1 && b == -1 && c == -1) return 0;//-1 -1 -1就直接结束,不运算了。
printf("w(%lld, %lld, %lld) = ", a, b, c);
printf("%lld\n", w(a, b, c));
}
}
感觉还需要掌握记忆话搜索的精髓
P1025 [NOIP2001 提高组] 数的划分
题目描述
将整数nnn分成kkk份,且每份不能为空,任意两个方案不相同(不考虑顺序)。
例如:n=7n=7n=7,k=3k=3k=3,下面三种分法被认为是相同的。
1,1,51,1,51,1,5;
1,5,11,5,11,5,1;
5,1,15,1,15,1,1.
问有多少种不同的分法。
输入格式
n,kn,kn,k (6<n≤2006<n \le 2006<n≤200,2≤k≤62 \le k \le 62≤k≤6)
输出格式
111个整数,即不同的分法。
#include<iostream>
using namespace std;
int n,k;
inline int dfs(int num,int part,int now)//剩余待分的数 分的机会数 现在要选出的数
{
if(part==1)return 1;
int sum=0;
for(int i=now;i<=num/part;i++)
{
sum+=dfs(num-i,part-1,i);
}
return sum;
}
int main()
{
cin>>n>>k;
cout<<dfs(n,k,1)<<endl;
}
感觉又是一道很好的dfs题 但是这个的动态规划感觉有点难想 转移方程不大会写呢