动态规划优化之使用Map记忆化搜索

已此题为例:

http://acm.hdu.edu.cn/showproblem.php?pid=1864


原来的解法:

http://blog.csdn.net/gaotong2055/article/details/8579388


上面的解法中DFS太耗时。就算是使用典型的动态规划,耗费空间,数组开的太大,有很多浪费,有太多的无用循环,也会耗时(200ms左右)。

这里使用map存数中间值,节省了空间和时间。



#include <stdio.h>
#include <string.h>
#include <iostream>
#include <map>
using namespace std;
double data[31];
int len,maxa;
double ans,q;



class OPT{
public:
	int k;
	double d;
	OPT(int a,double b):k(a),d(b){}
	OPT(){}
	bool operator == (const OPT & o) const{
		return k==o.k && d==o.d;
	}
	bool operator < (const OPT & o) const{
		if(k == o.k)
			return d < o.d;
		else
			return k < o.k;
	}
};

map<OPT,double> opts; //存储中间结果

double dfs(int k,double remain)
{
	OPT tmp(k, remain);
	if(opts[tmp] )
		return opts[tmp];
    if(k>=len)
    {
        return 0;
    }
    if(remain >= data[k])
    	return opts[tmp] = max(dfs(k+1,remain-data[k])+data[k], dfs(k+1,remain));
    else
    	return opts[tmp] = dfs(k+1,remain);
	return 0;
}

int main()
{
    int n,m;
    char cc;

    while(scanf("%lf %d",&q,&n)&&n!=0)
    {
        len=0;ans=-1;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&m);
            double a=0,b=0,c=0,temp,sum=0;
            int flag=1;
            while(m--)
            {
                scanf(" %c:%lf",&cc,&temp);
                if(cc=='A') a+=temp;
                else if(cc=='B') b+=temp;
                else if(cc=='C') c+=temp;
                else    flag=0;
                sum+=temp;
            }
            if(flag&&sum<=1000&&a<=600&&b<=600&&c<=600)
                data[len++]= sum ;
        }
        opts.clear();
        ans =  dfs(0,q);
        printf("%.2f\n",ans);
    }
}


你可能感兴趣的:(动态规划优化之使用Map记忆化搜索)