uva242,Stamps and Envelope Size

这题紫薯上翻译错了

应该是:如果有多个并列,输出邮票种类最少的那个,如果还有并列,输出最大面值最小的那个

坑了我一个下午

dp[p][q]==1表示可以用不超过q张组成面额p

结合记忆化,p从1开始枚举,一直枚举找到dp[p][q]=0的时候就可以了

这题应该归类成一种背包吧

注意dp初始化的时候应该初始化为-1(我就因为粗心,tle好久)

最后输出的时候比较恶心

最终的修改后的代码

 

实验证明,先读入所有数据后再处理比边读数据边处理要快

/*

 * Author:  Bingo

 * Created Time:  2015/3/4 13:54:40

 * File Name: uva242.cpp

 */

#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <string>

#include <vector>

#include <stack>

#include <queue>

#include <set>

#include <time.h>

using namespace std;

const int maxint = 1000000;

int S,T,n;

int map[20][20];

int dp[1200][20];

//int ans[20][20];

int ans,ans_num,ans_max,ans_case;

int fun(int p,int q,int c){

    if (dp[p][q]!=-1) return dp[p][q];

    else if (p==0){

        dp[p][q]=1;

        return 1;

    }else if (q==0) {

        dp[p][q]=0;

        return 0;

    }else {

        for (int i=1;i<=map[c][0];i++) {

            if (p>=map[c][i]&&fun(p-map[c][i],q-1,c)){

                dp[p][q]=1;

                return 1;

            }

        }

    }

    dp[p][q]=0;

    return 0;

}

int cmp(int a,int b){//比较最大连续邮资相同的集合   

    if(map[a][0]<map[b][0])return a;  

    if(map[b][0]<map[a][0])return b;  

    for(int i=map[a][0];i>0;i--){  

        if(map[a][i]<map[b][i])return a;  

        if(map[b][i]<map[a][i])return b;  

    }  

    return a;  

}  

int main(){

    while (cin>>S&&S){

        cin>>T;

        int mycase=0;

        ans=0;ans_num=maxint;ans_max=maxint;

        while (T--){

            cin>>n;

            mycase++;

            memset(dp,-1,sizeof(dp));

            map[mycase][0]=n;

            for (int i=1;i<=n;i++) {

                cin>>map[mycase][i];

            }

            int p;

            for (p=1;;p++) {

                if (fun(p,S,mycase)==0) break;

            }

            int t=p-1;

            if (t>ans){

                ans=t;

                ans_case=mycase;

            }else if (t==ans){

                ans_case=cmp(mycase,ans_case);

            }

        }

        printf("max coverage =%4d :", ans);

        for(int i=1;i<=map[ans_case][0];i++){

            printf("%3d",map[ans_case][i]);

        }

        printf("\n");

    }

    return 0;

}
View Code

 

你可能感兴趣的:(size)