dp之完全背包poj2063

题意:求投资k年获得最大投资,每年都选最大利息的方案进行投资k年后就可以得到最多的人民币。

注意:每一年收到的利息都可以作为下一年的本金......其实从测试数据来看,是很好看出来的......

思路:将每一年的“体积”加上利息就好,当然,数据太大,可以除以100减少时间和空间复杂度......

反思:很想说,这些我都想到了,但是还是wa了两次,是因为数据溢出的原因......以前就遇到这样的原因,木有想到这次我注意了,但还是出问题了......

wa代码:


#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int dp[500000],s[100][2];
int main()
{
	int text;
	scanf("%d",&text);
	while(text--)
	{
		int n,year;
		scanf("%d%d",&n,&year);
		int h,m=n/100;
		scanf("%d",&h);
		for(int i=1;i<=h;i++)
		{
			scanf("%d%d",&s[i][0],&s[i][1]);
			s[i][0]/=100;
		}
		memset(dp,0,sizeof(dp));
		int sum=0;
		for(int i=1;i<=year;i++)
		{
			
			for(int j=1;j<=h;j++)
			{
				for(int k=s[j][0];k<=m;k++)
				if(dp[k]<dp[k-s[j][0]]+s[j][1])
				dp[k]=dp[k-s[j][0]]+s[j][1];
			}
			sum+=dp[m];
			m=m+dp[m]/100;       //这里数据溢出,要是上一次的m==100,dp[m]==250,这一次的dp[m]==350,那么计算出来的m==105,但是实际应该为106 
		}
		printf("%d
",sum+n);
	}
	return 0;
}

 ac代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int dp[600000],s[100][2];
int main()
{
    int text;
    scanf("%d",&text);
    while(text--)
    {
        int n,year;
        scanf("%d%d",&n,&year);
        int h,m=n/100;
        scanf("%d",&h);
        for(int i=1;i<=h;i++)
        {
            scanf("%d%d",&s[i][0],&s[i][1]);
            s[i][0]/=100;
        }
        memset(dp,0,sizeof(dp));
        int sum=n;
        for(int i=1;i<=year;i++)
        {
            m=sum/100;
            for(int j=1;j<=h;j++)
            {
                for(int k=s[j][0];k<=m;k++)
                if(dp[k]<dp[k-s[j][0]]+s[j][1])
                dp[k]=dp[k-s[j][0]]+s[j][1];
            }
            sum+=dp[m];                     //以后的代码要规范写,可以在前面处理了的值不要留在后面处理....... 
        }
        printf("%d
",sum);
    }
    return 0;
}
 
原文地址:https://www.cnblogs.com/ziyi--caolu/p/3214100.html