切割问题(包含切割成本)

// dongtaiguihua.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int num[11];
#define c 2;
int p[] = { 0,1,5,8,9,10,17,17,20,24,30 };

自顶向下递归实现/
int cut(int p[], int n)
{
	if (n == 0)
		return 0;
	int q = -65536;
	for (int i = 1; i <= n; i++)
		q = max(q, p[i] + cut(p, n - i));
	return q;
}
///

带记录自顶向下
int m_cut_a(int p[], int n, int r[])
{
	int q,maxid=-65536;
	if (r[n] >= 0)
		return r[n];
	if (n == 0)
		q = 0;
	else {
		q = -65536;
		for (int i = 1; i <= n; i++) {
			if (q < p[i] + m_cut_a(p, n-i, r)) {
				q = p[i] + m_cut_a(p, n-i, r);
				maxid = i;
			}
		}
		num[n] = maxid;
		//判断有没有切割,没切割则更新上一步的方案
		if (maxid != n)q = q - 2;
		if (q < p[n]) {
			num[n] = n;
			q = p[n];
		}
	}
	r[n] = q;
	return q;
}


int m_cut(int p[], int n)
{
	int r[11];      //看数据,只有10个有效数据
	int sum;
	for (int i = 0; i <= n; i++)
		r[i] = -65535;
	sum=m_cut_a(p, n, r);
	while (n > 0) {
		cout << num[n] << endl;
		n = n - num[n];
	}
	return sum;
}
//自底向上///
int b_cut(int p[], int n, int *s)
{
	int r[11];
	int q;
	r[0] = 0;
	for (int i = 1; i <= n; i++)
	{
		q = -65535;
		 for (int j = 1; j <= i; j++) {
			 if (q < p[j] + r[i - j]) {
				 q = p[j] + r[i - j];
				 s[i] = j;
			 }
			
		 }
		 //判断有没有切割,没切割则更新上一步的方案
		 if (s[i] != i)q = q - 2;   
		 if (q < p[i]) {
			 s[i] = i;
			 q = p[i];
		 }
		 r[i] = q;
	}
	return r[n];
}

void print_b_cut(int p[], int n, int *s)
{
	int r;
	r = b_cut(p, n, s);
	cout << r << endl;
	while (n > 0) {
		cout << s[n]<<endl;
		n = n - s[n];
	}
}

int main()
{
	//cout<< cut(p, 10);
	//cout << m_cut(p, 8) << endl;;  //只有10个有效数据,故输入不能超过10
	int *s = (int*)malloc(sizeof(int));
	print_b_cut(p, 8, s);
	while (1);
    return 0;
}

  

转载于:https://www.cnblogs.com/linear/p/6599015.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值