poj 2063 Investment 完全背包问题

上来根据题目盲写完全背包

第一版代码

#include <iostream>
#include <stdio.h>
#include <stdio.h>
#include <cstring>

using namespace std;

int BONDS[11],INTERNEST[11];

int START,YEARS;
#define MAX_F 3800000
int F[MAX_F];
int G[MAX_F];

#define printf //
int main()
{
	int N;
	while(cin>>N)
	{
		int bound_nums;
		cin>>START>>YEARS;
		// START <= 100W YEARS <= 40
		cin>> bound_nums; // bound_nums <=  10
		for(int i=1;i<=bound_nums;i++)
		{
			cin>>BONDS[i]>>INTERNEST[i];
			INTERNEST[i] += BONDS[i];
			printf("bonds %d: %d %d\n",i,BONDS[i],INTERNEST[i]);
		}

		for(int y=1;y<=YEARS;y++)
		{

			printf("before %d years: %d\n",y,START);
			memset(F,0,sizeof(F));
			memset(G,0,sizeof(G));
			for(int i=1;i<=bound_nums;i++)
			{
				printf("************i=%d\n",i);
				for(int v=BONDS[i];v <= START ;v++)
				{
					int vlasti = F[ v-  BONDS[i] ] + INTERNEST[i];

					if(vlasti > F[v]) //买入第
					{
						F[v] = vlasti;
						G[v] = BONDS[i] + G[v -BONDS[i] ];


						printf("F[%d] =%d G[%d]=%d BONDS[%d]=%d\n",v,F[v],v,G[v],i,BONDS[i]);
					}
				}
			}

			int maxv = -1;
			int maxg = -1;

			for(int v=START;v>=0;--v)
				if(F[v] > maxv)
				{
					maxv = F[v];
					maxg = G[v];
				}

			START = maxv + (START - maxg); //这里要处理投资用掉的。剩下的要累积到下一年中去
			printf("after %d years: %d maxg :%d \n",y,START,maxg);
		}

		cout<<START<<endl;
	}
}


不是内存MLE 就是RE


尝试第内存进行优化,注意到题目中的一句话:The value of a bond is always a multiple of $1 000.
就是基金都是1000的倍数。

100万本金,40年,每年按1.1比率算,40年后就是4400万。

如果除以1000的话,就是4.4万。优化效果还是很明显的。


第二版代码

Source Code

Problem: 2063		User: csjiaxin
Memory: 832K		Time: 407MS
Language: C++		Result: Accepted
Source Code
#include <iostream>
#include <stdio.h>
#include <stdio.h>
#include <cstring>

using namespace std;

int BONDS[11],INTERNEST[11],INTERNESTMOD[11];

int START,YEARS,STARTMOD;
#define BASE 1000
#define MAX_F 50000
//100W *1.1 40次幂最多为4400W ,/1000最多为4.4万
int  F[MAX_F];
int  G[MAX_F];

int FMOD[MAX_F];

#define printf //
int main()
{
	int N;
	while(cin>>N)
	{
		for(int _n = 1;_n<=N;_n++)
		{
			int bound_nums;
			cin>>START>>YEARS;
			// START <= 100W YEARS <= 40
			cin>> bound_nums; // bound_nums <=  10
			for(int i=1;i<=bound_nums;i++)
			{
				cin>>BONDS[i]>>INTERNEST[i];
				INTERNEST[i] += BONDS[i];
	
				INTERNESTMOD[i] = INTERNEST[i] % BASE;
				INTERNEST[i] /= BASE;
				BONDS[i] /= BASE;
				printf("bonds %d: %d %d %d\n",i,BONDS[i],INTERNEST[i],INTERNESTMOD[i]);
			}
	
	
			STARTMOD = START%BASE;
			START /= BASE;
	
			for(int y=1;y<=YEARS;y++)
			{
	
				printf("before %d years: %d,%d\n",y,START,STARTMOD);
				memset(F,0,sizeof(F));
				memset(G,0,sizeof(G));
				memset(FMOD,0,sizeof(FMOD));

				for(int i=1;i<=bound_nums;i++)
				{
					printf("************i=%d\n",i);
					for(int v=BONDS[i];v <= START ;v++)
					{
						int last_index = v-BONDS[i];

						int vlasti = F[ last_index ] + INTERNEST[i];
						int vlastimod = FMOD[ last_index] + INTERNESTMOD[i];

						vlasti += vlastimod / 1000;
						vlastimod %= 1000; //这里注意下
						if(vlasti > F[v] || ( vlasti == F[v] && vlastimod > FMOD[v] )) //买入第
						{
							F[v] = vlasti;
							FMOD[v] = vlastimod;
	
							F[v] += FMOD[v] / BASE;
							FMOD[v] %= BASE;
							G[v] = BONDS[i] + G[v -BONDS[i] ];
	
							printf("F[%d] =%d G[%d]=%d BONDS[%d]=%d FMOD[%d]=%d\n",v,F[v],v,G[v],i,BONDS[i],v,FMOD[v]);
						}
					}
				}
	
				int maxv = -1;
				int maxg = -1;
				int maxmod = -1;
	
				for(int v=START;v>=0;--v)
					if(F[v] > maxv || (F[v] == maxv && FMOD[v] > maxmod))
					{
						maxv = F[v];
						maxg = G[v];
						maxmod = FMOD[v];
					}
	
				START = maxv + (START - maxg); //这里要处理投资用掉的。剩下的要累积到下一年中去
				STARTMOD += maxmod;
				
				START += STARTMOD/BASE;
				STARTMOD %= BASE;
				printf("after %d years: %d,%d maxg :%d \n",y,START,STARTMOD,maxg);
			}
	
			cout<<START*BASE+STARTMOD<<endl;
		}
	}
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值