• 习题9-5 UVA 242


    Stamps and Enovelope Size

    题意:

    给你最多贴S张邮票。有N个邮票集合,每个集合有不同的面值。问哪个集合的最大连续邮资最大,输出最大连续邮资和集合元素。

    如果不止一个集合结果相同,输出集合元素少的,如果仍相同,输出最大面值小的。

    思路:

    最开始直接进行的深搜,感觉应该会TL,就放弃了。主要是莫有想到记忆化搜索的使用 - -, 果然太年轻。

    用dp[i][j]表示使用了j个邮票后还差i,。
    记忆化搜索找出最大的可能,如果有相同的则进行比较


    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    using namespace std;
    const int maxn = 1005;
    int tp[15][15];
    int a[15];
    int n,num;
    int dp[maxn][12];
    
    int fin(int c,int cur,int sum)
    {
        if(sum > num)
            return dp[cur][sum] = 0;
        if(dp[cur][sum] != -1)
            return dp[cur][sum];
    
        if(sum == num && cur != 0)
            return dp[cur][sum] = 0;
        if(cur == 0)
            return dp[cur][sum] = 1;
        for(int i = 1; i <= tp[c][0]; i++)
        {
            if(cur < tp[c][i])
                continue;
            dp[cur][sum] = fin(c,cur-tp[c][i],sum+1);
            if(dp[cur][sum] == 1)
                return 1;
        }
        return dp[cur][sum];
    }
    
    int get_(int a,int b)
    {
        if(tp[a][0]<tp[b][0])return a;                  //比长度
        if(tp[b][0]<tp[a][0])return b;
        for(int i=tp[a][0]; i>0; i--)
        {
            if(tp[a][i]<tp[b][i])return a;              //比最大值
            if(tp[b][i]<tp[a][i])return b;
        }
        return a;
    }
    
    int main()
    {
        while(scanf("%d",&num)!= EOF && num)
        {
            scanf("%d",&n);
            for(int i = 1; i <= n; i++)
            {
                scanf("%d",&tp[i][0]);
                for(int j = 1; j <= tp[i][0]; j++)
                {
                    scanf("%d",&tp[i][j]);
                }
            }
    
    
            int tans = -1;
            int ans = -1;
            for(int i = 1; i <= n; i++)
            {
                int tt = 0;
                int t = 0;
                memset(dp,-1,sizeof(dp));
                for(int j = 1;; j++)
                {
                    if(fin(i,j,0))
                    {
                        tt = j;
                        t = i;
                    }
                    else
                        break;
                }
                if(ans < tt)
                {
                    ans = tt;
                    tans = t;
                }
                else if(ans == tt)
                {
                    tans = get_(t,tans);
                }
            }
            printf("max coverage =%4d :",ans);
            for(int i = 1; i <= tp[tans][0]; i++)
            {
                printf("%3d",tp[tans][i]);
            }
            printf("
    ");
        }
    }
    

      


  • 相关阅读:
    OKHttp的使用
    多点触控
    事件分发机制的理解
    Activity的四种启动模式
    反射动态建表
    px,dp,sp三者的转换
    动态广播和静态广播的区别
    字符串转日期格式
    hive Metastore contains multiple versions
    记一次 qW3xT.4,解决挖矿病毒。
  • 原文地址:https://www.cnblogs.com/Przz/p/5409681.html
Copyright © 2020-2023  润新知