我來講講 \(dp\) 的做法
前言
昨天 \(PHY\) 大佬問我,這題怎么做?考慮到他沒學過 \(set\) 、 \(priority_queue\) 和 \(queue\) 。之后,我就想到了可以用 \(dp\) 來解決這道題。
正文
設置狀態
很顯然,我們可以用 \(f[i]\) 表示第\(i\)個數是多少。
轉移
第\(i\)個\(H\)數是多少,我們顯然應該從前面的\(i-1\)個數去分別\(\times2\)、\(\times3\)、\(\times5\)、\(\times7\)中取比第\(i-1\)個\(H\)數大的最小數。
邊界條件
\(f_1=1\)是很顯然的
此外還要注意\(f_0=0\)
代碼
我們現在就可以開始寫代碼了
注意開\(long\) \(long\)
#include <bits/stdc++.h>
using namespace std;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
template<typename T>void write(T x){
if(x<0)putchar('-'),x*=-1;
if(x>9)write(x/10);
putchar(x%10+48);
}
long long f[10010];
int main(){
memset(f,127,sizeof(f));//為了找最小,我們最開始就得賦成最大
int n;
read(n);
f[0]=0;//初始化
f[1]=1;//初始化
for(int i=2;i<=n;i++)
for(int j=i-1;j>=1;j--)
if(f[j]*2>f[i-1])f[i]=min(f[i],f[j]*2);
else if(f[j]*3>f[i-1])f[i]=min(f[i],f[j]*3);
else if(f[j]*5>f[i-1])f[i]=min(f[i],f[j]*5);
else if(f[j]*7>f[i-1])f[i]=min(f[i],f[j]*7);
else break;//優化
write(f[n]);//輸出
return 0;
}
后記
這個代碼還是很簡短的,十分好寫,希望大家以后學習也能好好想想一題多解
最后來求一下贊和評論!
