【动态规划入门】FOJ1320 Ones

本文介绍了动态规划解决FOJ1320 Ones问题的方法,旨在帮助初学者入门。题目要求找到一个由1、+、*、(、)组成的表达式,使得其值等于给定的整数n,且1不连续。通过动态规划策略,将问题拆分为子问题,分别求解最少1的数量。例如,n=2时答案为2,n=10时答案为7。文章详细阐述了动态规划的状态转移方程和解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【动态规划入门】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];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值