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

来源:互联网 发布:网络培训工程平台 编辑:程序博客网 时间:2024/05/18 22:45

已此题为例:

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;elsereturn 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);    }}