最近自己感觉动态规划这方面太差,就在各大oj上找了一些基础的dp题来A啊。
这个dp题,虽说是入门的。但对于我,也有些棘手啊!
1-->1
2--->min(1*2,1*3,1*5,1*7)---->2
3--->min(2*2,1*3,1*5,1*7)----->3
4---->min(2*2,2*3,1*5,1*7)----->4;
5---->min(2*3,2*3,1*5,1*7)----->5;
......................
如果知道上面的转移,这题的状态方程就明了了:
f(n)=min(2*f(a),3*f(b),5*f(c),7*f(d)) (只有当某一项被选了,才会相应地增加某项)
#include<stdio.h>
long num[6000];
long min(long x,long y)
{
return x<y?x:y;
}
void solve()
{
int t,a,b,c,d;
t=a=b=c=d=1;
num[1]=1;
for(int i=2;i<=5842;i++){
num[++t]=min(min(2*num[a],3*num[b]),min(5*num[c],7*num[d]));
if(num[t]==2*num[a]) a++;
if(num[t]==3*num[b]) b++;
if(num[t]==5*num[c]) c++;
if(num[t]==7*num[d]) d++; //不能用else if,有可能不同两个值相乘是相等的 (看上面的第4和5)
}
}
int main()
{
int n,t,s;
solve();
while(scanf("%d",&n)&&n){
printf("The ");
printf("%d",n);
t=n%10,s=n%100; //主意末尾两位数,比如12是12th,而22是22nd。
if(t==1&&s!=11) printf("st ");
else if(t==2&&s!=12) printf("nd ");
else if(t==3&&s!=13) printf("rd ");
else printf("th ");
printf("humble number is %ld.\n",num[n]);
}
}