【动态规划入门】FOJ1320 Ones
此题为动态规划入门级算法题,题目来源计科老班
题目描述
给一个整数n,要你找一个值为n的表达式,这个表达式只有1 + * ( ) 够成。并且1不能连续,比如11+1就不合法。
输入
n,(1<=n<=10000)
输出
输出最少需要多少个1才能构成表达式。
样例输入
2
10
样例输出
2
7
思路详解
此题数据庞大,应该采用动态规划,将原问题分解为若干个子问题,先求解子问题,然后从这些子问题得解得到原问题的解。
样例:n=2=1+1 ans=2
n=10=(1+1)(1+1+1+1+1) ans=7
此题需要,让f[i]表示最少数量的1能够表示i。无非两种情况,加法组成或者乘法组成。
add: f[i]=f[j]+f[i-j] 0<j<i
multiply: f[i]=f[j]+f[i/j] 0<j<i, i%j=0
首先,1和2固定是1个1组成和2个1组成,那么3就可以根据1和2的情况得到,3最优为3=1+1+1或者3=1(1+1)…6则为6=(1+1)(1+1+1),即2和3的最优解得到…10则为10=(1+1)*(1+1+1+1+1),即2和5最优解得到,因此,最终总问题分解为多个子问题解决,使用动态规划。
代码
#include<iostream>
using namespace std;
int A[10001];
int main() {
int n;cin>>n;
A[1]=1;A[2]=2;
for(int i=3;i<=n;i++) {
A[i]=i;
for(int k=1;k<i;k++) {
if(A[k]+A[i-k]<A[i]) A[i]=A[k]+A[i-k]; //加法
if(i%k==0 && A[k]+A[i/k]<A[i])
A[i]= A[k]+A[i/k];
}
}
cout<<A[n];
}