求算法。。noip动态规划的题。。。。要C语言的!!!!!!!!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求算法。。noip动态规划的题。。。。要C语言的!!!!!!!!相关的知识,希望对你有一定的参考价值。

资源分配问题
设有资源a分配给n个项目,gi(x)是数量为x(x<=a)的资源分配给项目i所能得到的利润,i=1,2,…,n最合理的资源分配导致解下面的问题:
max Z=g1(x1)+g2(x2)+…+gn(xn) 其中x1+x2+…+xn=a xi>=0,i=1,2,…,n。
例如:有7万元资本投资到A、B、C三种项目,其利润见表。
投资额
项目 1 2 3 4 5 6 7
A 0.12 0.15 0.20 0.21 0.24 0.30 0.36
B 0.22 0.24 0.26 0.28 0.30 0.33 0.34
C 0.18 0.22 0.26 0.28 0.30 0.34 0.36

设f[i,k]是将i万元投资到前k个项目得到的最高利润。
比如f[7,3]就是将7万元投资到前3个项目所得到的利润
那么你要得到的结果就是f[a,n]的数值罢了
根据题意
f[i,k]的递推公式可以写为
f[i,k]=max(f[i-j,k-1]+gk[j]) j=1……i-1
具体的实现过程就要你自己写了
算法就是这样,很简单的题
参考技术A 做动态规划的题,关键是找准状态,这个状态必须有最优子结构的特性,

以及无后效性,意思是后面做的决策不能影响前面的状态

这样子我们把每个状态的最优值都找到并储存下来,这样最后的状态,

也就是全局状态的最优值也就有了.

说白了,动态规划是一种以空间上的开销来节约时间上开销的方法

我这里还没找到 好的状态 这个是关键

分别用回溯法和动态规划求0/1背包问题(C语言代码)

希望在vc++6.0下编译通过,主要步骤有注释。满意后可追加分数!请不要网上复制。有 n 件物品, 每件物品有一个价值和一个重量,分别记为:
b1,b2, …bn
w1,w2, …wn
其中所有的 重量wi 均为整数。 现有一个背包,其最大载重量为W,要求从这n件物品中任取若干件(这些物品要么被装入要么被留下)。问背包中装入哪些物品可使得所装物品的价值和最大?

#include <stdio.h>
#include <malloc.h>
#include <windows.h>typedef struct goods

double *value; //价值
double *weight; //重量
char *select; //是否选中到方案
int num;//物品数量
double limitw; //限制重量
GOODS;
double maxvalue,totalvalue;//方案最大价值,物品总价值
char *select1; //临时数组
void backpack(GOODS *g, int i, double tw, double tv)//参数为物品i,当前选择已经达到的重量和tw,本方案可能达到的总价值

int k;
if (tw + g->weight[i] <= g->limitw)//将物品i包含在当前方案,且重量小于等于限制重量

select1[i] = 1; //选中第i个物品
if (i < g->num - 1) //若物品i不是最后一个物品
backpack(g, i + 1, tw + g->weight[i], tv); //递归调用,继续添加下一物品
else //若已到最后一个物品

for (k = 0; k < g->num; ++k) //将状态标志复制到option数组中
g->select[k] = select1[k];
maxvalue = tv; //保存当前方案的最大价值


select1[i] = 0; //取消物品i的选择状态
if (tv - g->value[i] > maxvalue)//若物品总价值减去物品i的价值还大于maxv方案中已有的价值,说明还可以继续向方案中添加物品

if (i < g->num - 1) //若物品i不是最后一个物品
backpack(g, i + 1, tw, tv - g->value[i]); //递归调用,继续加入下一物品
else //若已到最后一个物品

for (k = 0; k < g->num; ++k) //将状态标志复制到option数组中
g->select[k] = select1[k];
maxvalue = tv - g->value[i]; //保存当前方案的最大价值(从物品总价值中减去物品i的价值)



int main()

double sumweight;
GOODS g;
int i;
printf("背包最大重量:");
scanf("%lf",&g.limitw);
printf("可选物品数量:");
scanf("%d",&g.num);
if(!(g.value = (double *)malloc(sizeof(double)*g.num)))//分配内存保存物品价值

printf("内存分配失败\\n");
exit(0);

if(!(g.weight = (double *)malloc(sizeof(double)*g.num)))//分配内存保存物品的重量

printf("内存分配失败\\n");
exit(0);

if(!(g.select = (char *)malloc(sizeof(char)*g.num)))//分配内存保存物品的重量

printf("内存分配失败\\n");
exit(0);

if(!(select1 = (char *)malloc(sizeof(char)*g.num)))//分配内存保存物品的重量

printf("内存分配失败\\n");
exit(0);

totalvalue=0;
for (i = 0; i < g.num; i++)

printf("输入第%d号物品的重量和价值:",i + 1);
scanf("%lf%lf",&g.weight[i],&g.value[i]);
totalvalue+=g.value[i];//统计所有物品的价值总和

printf("\\n背包最大能装的重量为:%.2f\\n\\n",g.limitw);
for (i = 0; i < g.num; i++)
printf("第%d号物品重:%.2f,价值:%.2f\\n", i + 1, g.weight[i], g.value[i]);
for (i = 0; i < g.num; i++)//初始设各物品都没加入选择集
select1[i]=0;
maxvalue=0;//加入方案物品的总价值
backpack(&g,0,0.0,totalvalue); //第0号物品加入方案,总重量为0,所有物品价值为totalvalue
sumweight=0;
printf("\\n可将以下物品装入背包,使背包装的物品价值最大:\\n");
for (i = 0; i < g.num; ++i)
if (g.select[i])

printf("第%d号物品,重量:%.2f,价值:%.2f\\n", i + 1, g.weight[i], g.value[i]);
sumweight+=g.weight[i];

printf("\\n总重量为: %.2f,总价值为:%.2f\\n", sumweight, maxvalue );
// getch();
return 0;
参考技术A 你看你这个问题都没有人来回答,看来qq的金币还不值钱呢。、偶告诉你,使用metlab直接由 01 问题 工具包,直接调用函数解决

以上是关于求算法。。noip动态规划的题。。。。要C语言的!!!!!!!!的主要内容,如果未能解决你的问题,请参考以下文章

求动态规划0-1背包算法解释

分别用回溯法和动态规划求0/1背包问题(C语言代码)

用 Excel 做点无聊的题 —— “动态规划” 入门理解(上)

Codevs_1040_[NOIP2001]_统计单词个数_(划分型动态规划)

C语言每日一练 —— 第22天:动态规划

JZYZOJ1457 [NOIP2016]换教室 期望dp 动态规划 floyd算法 最短路