/*每段长度的钢筋对应不同的盈利,问怎样切割能盈利最多!
*
*
*/
// 自顶向下 递归 #include<cstdio> #include<cstring> #include<algorithm> using namespace std ; #define maxn 1000000 int p[maxn] ; int solve(int n){ if (n==0){ return 0 ; } int max_num = -maxn ; for(int i=1 ; i<=n ; i++){ max_num = max(max_num , p[i]+solve(n - i )) ; } return max_num ; } int main(){ int n ; while(~scanf("%d" , &n)){ for(int i=1; i<=n ; i++){ scanf("%d" , &p[i]) ; } int result = solve(n) ; printf("%d\n" , result) ; } return 0 ; }
带备忘的自顶向下递归
#include<cstdio> #include<cstring> #include<algorithm> using namespace std ; #define maxn 1000000 int p[maxn] ; int visit[maxn] ; int solve(int n){ if(visit[n]>=0){ return visit[n] ; } if (n==0){ return 0 ; } int max_num = -maxn ; for(int i=1 ; i<=n ; i++){ max_num = max(max_num , p[i]+solve(n - i )) ; } visit[n] = max_num ; return max_num ; } int main(){ int n ; while(~scanf("%d" , &n)){ for(int i=1; i<=n ; i++){ scanf("%d" , &p[i]) ; } // 盈利可能是 0 for(int i=0 ; i<=n ; i++){ visit[i] = -maxn ; } int result = solve(n) ; printf("%d\n" , result) ; } return 0 ; }
自底向上
#include<cstdio> #include<cstring> #include<algorithm> using namespace std ; #define maxn 1000000 int p[maxn] ; int visit[maxn] ; int solve(int n){ visit[0] = 0 ; for(int i=1 ; i<=n ; i++){ int max_num = -maxn ; for(int j=1 ; j<=i ; j++){ max_num = max(max_num , p[j]+visit[i-j]) ; } visit[i] = max_num ; } return visit[n] ; } int main(){ int n ; while(~scanf("%d" , &n)){ for(int i=1; i<=n ; i++){ scanf("%d" , &p[i]) ; } int result = solve(n) ; printf("%d\n" , result) ; } return 0 ; }
自底向上记录最优解对应的切割方案
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<cstdio> #include<cstring> #include<algorithm> using namespace std ; #define maxn 1000000 int p[maxn] ; int visit[maxn] ; int cut[maxn] ; int solve(int n){ visit[0] = 0 ; for(int i=1 ; i<=n ; i++){ int max_num = -maxn ; for(int j=1 ; j<=i ; j++){ if(max_num < p[j]+visit[i-j]){ max_num = p[j]+visit[i-j] ; cut[i] = j ; } } visit[i] = max_num ; } return visit[n] ; } int main(){ int n ; while(~scanf("%d" , &n)){ for(int i=1; i<=n ; i++){ scanf("%d" , &p[i]) ; } for(int i=0 ; i<=n ; i++){ visit[i] = -maxn ; cut[i] = 0 ; } int result = solve(n) ; while(n){ printf("%d " , cut[n]) ; n = n-cut[n] ; } printf("%d\n" , result) ; } return 0 ; }