题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2018
解题思路:
①尝试暴力打表(欲DP,先暴力)
失败,最后遍历次数太多炸了。
代码:
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int dp[100];
vector<int>v;
void pt()
{
int year=1;
dp[1] = 1;
v.push_back(4);
while (++year<=54){
int cnt = 0;
for(int i=0;i<v.size();i++){
if (v[i]>=3) cnt++;
v[i]++;
}
for (int i=0;i<cnt;i++) v.push_back(1);
printf("第%d年:%d只\n",year,v.size());
dp[year] = v.size();
}
}
int main()
{
pt();
int n;
while (scanf("%d",&n),n){
printf("%d\n",dp[n]);
}
return 0;
}
②暴力后发现不用这么麻烦,记录上一年最后一天 >=3,2,1岁的就行
代码:(可以AC)
#include<cstdio>
int dp[60];
void pt()
{
int a=1,b=0,c=0;///分别表示这一年过去之后 大于等于3岁,等于2岁, 等于1岁
int year = 1;
dp[1] = 1;
while (++year<=54){
int newcow = a;
a += b;
b = c;
c = newcow;
dp[year] = a+b+c;
}
}
int main()
{
pt();
int n;
while (scanf("%d",&n),n){
printf("%d\n",dp[n]);
}
return 0;
}
③ 再想想,怎么和DP联系起来,发现dp[i] = dp[i-1] + dp[i-3]
今天的牛 = 去年的牛+可以生的牛
代码:
#include<cstdio>
int dp[60];
void pt()
{
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
for (int i=4;i<=54;i++) dp[i] = dp[i-1] + dp[i-3];
}
int main()
{
pt();
int n;
while (scanf("%d",&n),n){
printf("%d\n",dp[n]);
}
return 0;
}