POJ 1010 题目翻译+题解
题目实在是太难懂了,我翻译了一下。。。
STAMPS 
Description 
Have you done any Philately lately?  
你最近有没有集邮?
You have been hired by the Ruritanian Postal Service (RPS) to design their new postage software. The software allocates stamps to customers based on customer needs and the denominations that are currently in stock.  
你被鲁里坦尼亚王国(浪漫国)邮政服务雇佣去设计他们新的邮资软件。这个软件分配以客户需求为基础的邮票数量和目前股票的面额。
Ruritania is filled with people who correspond with stamp collectors. As a service to these people, the RPS asks that all stamp allocations have the maximum number of different types of stamps in it. In fact, the RPS has been known to issue several stamps of the same denomination in order to please customers (these count as different types, even though they are the same denomination). The maximum number of different types of stamps issued at any time is twenty-five.  
浪漫国充满了集邮的人。作为对这些人的服务,浪漫国邮政服务要求所有的邮票分配不同类型的邮票种类以及它的最大数目。事实上,RPS还发行以一些面额相同的邮票来取悦客户(这些算不同的类型,即使它们是相同的面额)发行的不同邮票的种类的最大数目是二十五。
To save money, the RPS would like to issue as few duplicate stamps as possible (given the constraint that they want to issue as many different types). Further, the RPS won’t sell more than four stamps at a time.  
为了省钱,浪漫国邮政服务发行的邮票数量越少越好(强制发行的种类越多越好)。进一步讲,浪漫国邮政服务不会在同一时间卖四张邮票以上。(注:其实就是顾客不能拿四张邮票以上) 
Input 
The input for your program will be pairs of positive integer sequences, consisting of two lines, alternating until end-of-file. The first sequence are the available values of stamps, while the second sequence is a series of customer requests.  
输入的程序将是正整数序列,由两行组成,交替直到文件结束。 
第一行是邮票的价值。而第二行是一系列的客户要求。(注:第一行数字是邮票的面值,每一个数字就是一个不同的种类,哪怕面值相同。以0结束。第二行数字是顾客所需要的邮票总面值。每个数字就是一个顾客的需求,以0结束。) 
For example: 举个例子 
1 2 3 0 ; three different stamp types   //三个不同种类的邮票 
7 4 0 ; two customers   //两个顾客 
1 1 0 ; a new set of stamps (two of the same type) //新的邮票的集合 
6 2 3 0 ; three customers //三个顾客
Note: the comments in this example are not part of the data file; data files contain only integers.//对话不是文件的内容,文件只包含整数。 
Output 
For each customer, you should print the “best” combination that is exactly equal to the customer’s needs, with a maximum of four stamps. If no such combination exists, print “none”.  
对于每一个顾客,你应该输出最好的组合(完全等同于客户的要求的组合),最多4张邮票。如果不存在这样的组合,输出“none”。
The “best” combination is defined as the maximum number of different stamp types. In case of a tie, the combination with the fewest total stamps is best. If still tied, the set with the highest single-value stamp is best. If there is still a tie, print “tie”.  
“最佳”组合被定义为不同类型的标记类型的最大数目。在平局的情况下,用最少的总邮票的组合是最好的。如果还平局着,有最高的单值邮票是最好的。如果还平局,输出“tie”。 
For the sample input file, the output should be:  
对于样例输入,输出应该是: 
7 (3): 1 1 2 3  
4 (2): 1 3  
6 —- none  
2 (2): 1 1  
3 (2): tie
That is, you should print the customer request, the number of types sold and the actual stamps. In case of no legal allocation, the line should look like it does in the example, with four hyphens after a space. In the case of a tie, still print the number of types but do not print the allocation (again, as in the example).Don’t print extra blank at the end of each line.  
也就是说,你应该输出客户的要求,出售的类型和实际邮票的数量。没有合法的分配,输出应该像样例里的那样,一个空格后面四个连字符。对于平局的情况,仍输出类型,但不输出分配的数量(再说一遍,就像样例里的那样),行末不要加空格。 
样例输入输出不解释了。。。 
Sample Input 
1 2 3 0 ; three different stamp types 
7 4 0       ; two customers 
1 1 0       ; a new set of stamps (two of the same type) 
6 2 3 0 ; three customers 
Sample Output 
7 (3): 1 1 2 3  
4 (2): 1 3  
6 —- none 
2 (2): 1 1 
3 (2): tie
题目还是比较难懂。。。 
解释一下: 
由于每次有多种组合,那么如何取结果呢? 
如果这些组合都能满足用户的的需求,那么 
1.选种类最多的 
2.如果种类相同,选总数最多的 
3.如果总数相同,选邮票值组合最大值最大的那一组 
4.如果连最大值也相同,那么就是tie 
5。如果没有这样的组合,也就是不能用4张以内的邮票满足顾客,那么就是none 
输出格式,第一个是总价值,括号里面的是邮票的种类,后面是相应的值。 
(摘自http://blog.csdn.net/zhang20072844/article/details/6685353)
思路:DFS +剪枝    自己写了个传5个值的DFS,回溯出了点儿问题 
剪枝:1.不能选超过4张邮票(显然的剪枝) 
            2.把邮票按升序排序,从小到大选(因为种类越多越好,邮票面值小的时候,选的种类肯定是要多一点儿的) 
(写了挺长时间,,特别容易在回溯的时候出错)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int alen,blen,a[66],b[66],jy,jyy[66],vis[66];
bool tied,printed;
void dfs(int max_kind,int min_num,int max_money,int x,int pre)
{
    if(min_num>4) return;//不能选四张以上的邮票
    if(x==jy)//和b[i]的值相等
    {
        if(max_kind>jyy[alen+1])//jyy[alen+1]表示kind的最大值
        {
            tied=false;//如果有新的解,要把tied赋值成false
            for(int i=1;i<=alen;i++)
                jyy[i]=vis[i];
            jyy[alen+1]=max_kind;
            jyy[alen+2]=min_num;
            jyy[alen+3]=max_money;
        }
        else if(max_kind==jyy[alen+1])
        {
            if(min_num<jyy[alen+2])//jyy[alen+2]表示num的最小值
            {
                for(int i=1;i<=alen;i++)
                    jyy[i]=vis[i];
                jyy[alen+2]=min_num;
                jyy[alen+3]=max_money;
                tied=false;
            }
            else if(min_num==jyy[alen+2])
            {
                if(max_money>jyy[alen+3])////jyy[alen+3]表示money的最大值
                {
                    for(int i=1;i<=alen;i++)
                        jyy[i]=vis[i];
                    jyy[alen+3]=max_money;
                    tied=false;
                }
                else if(max_money==jyy[alen+3])
                    tied=true;
            }
        }
    }
    int temp;
    for(int i=pre;i<=alen;i++)//i从pre开始,(技巧剪枝)
    {
        if(vis[i]<=4)
        {
            if(!vis[i])max_kind++;//多少种
            vis[i]+=1;
            if(max_money<=a[i])
            {
                max_money=a[i];
                temp=max_money;
            }
            dfs(max_kind,min_num+1,max_money,x+a[i],i);
            vis[i]=vis[i]-1;
            if(vis[i]==0)
            {
                max_kind--;
                if(a[i]==max_money)
                {
                    a[i]=temp;
                }
            }
        }
    }
}
int main()
{
    scanf("%d",&a[1]);//比较坑的循环方式
    start:
        tied=false;
        for(int i=2;;i++)//读入  不解释
        {
            scanf("%d",&a[i]);
            if(a[i]==0)
            {
                alen=i-1;
                break;
            }
        }
        sort(a+1,a+1+alen);//从小到大排序,为了剪枝
        for(int i=1;;i++)
        {
            scanf("%d",&b[i]);
            if(b[i]==0)
            {
                blen=i-1;
                break;
            }
        }
        for(int i=1;i<=blen;i++)
        {
            tied=printed=0;
            jyy[alen+2]=0x3f3f3f3f;//num是选最小值的,所以赋值成极大值
            memset(vis,0,sizeof(vis));
            memset(jyy,0,sizeof(jyy));
            jy=b[i];
            dfs(0,0,0,0,1);//pre要从1开始
            if(tied) printf("%d (%d): tie\n",jy,jyy[alen+1]);
            else
            {
                for(int i=1;i<=alen;i++)
                    if(jyy[i]!=0) printed=true;
                if(!printed)
                    printf("%d ---- none\n",jy);
                else
                {
                    printf("%d (%d): ",jy,jyy[alen+1]);
                    for(int i=1;i<=alen;i++)
                    {
                        for(int j=1;j<=jyy[i];j++)
                        {
                            if(i==alen&&j==jyy[i])printf("%d",a[i]);
                            else printf("%d ",a[i]);
                        }
                    }
                    printf("\n");
                }
            }
        }
    if(scanf("%d",&a[1])!=EOF) goto start;//循环回前面。
} POJ 1010 题目翻译+题解的更多相关文章
- POJ 2823 Sliding  Window 题解
		POJ 2823 Sliding Window 题解 Description An array of size n ≤ 106 is given to you. There is a sliding ... 
- poj 动态规划题目列表及总结
		此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 11 ... 
- POJ 动态规划题目列表
		]POJ 动态规划题目列表 容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276, 1322 ... 
- NOIP提高组题目归类+题解摘要(2008-2017)
		因为前几天作死立了一个flag说要把NOIP近十年的题目做一做,并写一个题目归类+题解摘要出来,所以这几天就好好的(然而还是颓废了好久)写了一些这些往年的NOIP题目. 这篇博客有什么: 近十年NOI ... 
- POJ 2585 Window Pains 题解
		链接:http://poj.org/problem?id=2585 题意: 某个人有一个屏幕大小为4*4的电脑,他很喜欢打开窗口,他肯定打开9个窗口,每个窗口大小2*2.并且每个窗口肯定在固定的位置上 ... 
- poj 1010
		http://poj.org/problem?id=1010 题意:给你n种邮票的价值,到0结束,这些邮票价值有可能相同,但是形状是不同的. 还有给你m个收藏家所需要收藏的邮票的总价格.到0结束. 每 ... 
- {POJ}{动态规划}{题目列表}
		动态规划与贪心相关: {HDU}{4739}{Zhuge Liang's Mines}{压缩DP} 题意:给定20个点坐标,求最多有多少个不相交(点也不相交)的正方形 思路:背包问题,求出所有的正方形 ... 
- [POJ 2115} C Looooops 题解(扩展欧几里德)
		题目描述 对于C的for(i=A ; i!=B ;i +=C)循环语句,给出A,B,C和k(k表示变量是在k进制下的无符号整数),判断循环次数,不能终止输出"FOREVER". 输 ... 
- poj 3258 River Hopscotch 题解
		[题意] 牛要到河对岸,在与河岸垂直的一条线上,河中有N块石头,给定河岸宽度L,以及每一块石头离牛所在河岸的距离, 现在去掉M块石头,要求去掉M块石头后,剩下的石头之间以及石头与河岸的最小距离的最大值 ... 
随机推荐
- redis键的过期和内存淘汰策略
			键的过期时间 设置过期时间 Redis可以为存储在数据库中的值设置过期时间,作为一个缓存数据库,这个特性是很有帮助的.我们项目中的token或其他登录信息,尤其是短信验证码都是有时间限制的. 按照传统 ... 
- java aop面向切面编程
			最近一直在学java的spring boot,一直没有弄明白aop面向切面编程是什么意思.看到一篇文章写得很清楚,终于弄明白了,原来跟python的装饰器一样的效果.http://www.cnblog ... 
- SQL一对多取子表最新记录的所有字段(ROW_NUMBER()OVER()函数的应用)
			ROW_NUMBER()OVER() 参数1:分组字段 PARTITION BY ..,..,.... 可选 参数2:排序字段 ORDER BY .. DESC 必须 实例: 根据Confir ... 
- 使用form标签时注意事项
			今天写程序的时候,使用了一个form:select标签,然后系统一直报错 原因找了好久也没找到 后来咨询得知, 在使用form:标签的时候 前后的form标签要写成<form:form> ... 
- js中数组,字符串,对象常用方法总结
			时间对象方法 获取当前时间的毫秒数 1.var timestamp = Date.parse(new Date()); 2.var timestamp = (new Date()).valueOf() ... 
- 关于Spring的69个问题
			Spring 概述 1. 什么是spring? Spring 是个java企业级应用的开源开发框架.Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用.Spring ... 
- noip模拟赛 SAC E#1 - 一道中档题 Factorial
			题目背景 数据已修改 SOL君(炉石主播)和SOL菌(完美信息教室讲师)是好朋友. 题目描述 SOL君很喜欢阶乘.而SOL菌很喜欢研究进制. 这一天,SOL君跟SOL菌炫技,随口算出了n的阶乘. SO ... 
- [bzoj3450]Tyvj1952 Easy[概率dp]
			和之前一样考虑这个音符时x还是o,如果是x,是否是新的连续一段,对答案的贡献是多少$(a^2-{(a-1)}^2)$,然后递推就可以了. #include <bits/stdc++.h> ... 
- angular的又一本好书
			MANNING出的<ANGULAR.JS IN ACTION>. 比上本看完的书<ANGULAR ESSENTIAL>多了一些有全局性的东东. 八个关键概念:MODULE,CO ... 
- Spring MVC-集成(Integration)-Hibernate验证器示例(转载实践)
			以下内容翻译自:https://www.tutorialspoint.com/springmvc/springmvc_hibernate_validator.htm 说明:示例基于Spring MVC ... 
