STAMPS
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 19296 | Accepted: 5651 |
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.
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.
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.
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. 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.
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".
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".
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.
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".
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
Source
Sample Input
1 2 3 0
7 4 0
1 1 0
6 2 3 0
1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0
2 8 0
1 2 3 4 5 6 7 8 9 10 0
2 5 10 20 33 0
1 1 6 0
4 5 0
Sample Output
7 (3): 1 1 2 3
4 (2): 1 3
6 ---- none
2 (2): 1 1
3 (2): tie
2 (2): 1 1
8 (4): tie
2 (1): 2
5 (2): 1 4
10 (4): 1 2 3 4
20 (4): tie
33 (4): 6 8 9 10
4 (2): tie
5 ---- none
先贴一个超时代码,之后优化
![](https://i-blog.csdnimg.cn/blog_migrate/19b8c7333c4fcb4d31be3c77bdfb15e0.png)
1 /* 2 深度优先搜索 3 利用map,下标表示邮票的种类,second表示计数值——邮票的张数 4 邮票的种类数不超过25 5 */ 6 #include<iostream> 7 #include<map> 8 #include<stdio.h> 9 using namespace std; 10 int stamp[120];//用来记录邮票的种类,由于不同种类的邮票面值可以相同, 11 //所以实际计算中采用的数组下标作为邮票的种类 12 map<int,int> bestx; 13 int bestp=0;//用来记录最优解邮票的张数 14 int bestTyp = 0;//用来记录最优解邮票的种数 15 int bestCount = 0;//用来记录最优解的个数,判断是否tie,注意需要在每次更新最优解的时候置0 16 map<int,int> x; 17 void UpDate(int Count,int Typ) 18 { 19 bestx.clear(); 20 map<int,int>::iterator iterUp = x.begin(); 21 for(iterUp;iterUp != x.end();iterUp++) 22 { 23 bestx.insert(pair<int,int>(iterUp->first,iterUp->second)); 24 } 25 bestp = Count; 26 bestCount = 0; 27 bestTyp = Typ; 28 } 29 void PrintAns(int m) 30 { 31 if(bestp == 0) 32 { 33 cout<<m<<" ---- none"<<endl; 34 }else if(bestCount > 0) 35 { 36 cout<<m<<"("<<bestTyp<<")"<<": tie"<<endl; 37 }else{ 38 cout<<m<<"("<<bestTyp<<")"<<":"; 39 map<int,int>::iterator iterTemp = bestx.begin(); 40 for(iterTemp;iterTemp != bestx.end();iterTemp++) 41 { 42 for(int i=0;i<iterTemp->second;i++) 43 cout<<" "<<stamp[iterTemp->first]; 44 } 45 cout<<endl; 46 } 47 } 48 void BackTrack(int t,int n,int m,int pre)//i=pre 剪枝,不重复搜索比当前面值小的邮票,同时避免错误的tie 49 {//n为邮票的种数,m为顾客需要邮票的金额数 50 int sum = 0;//计算当前邮票的总金额 51 map<int,int>::iterator iterSum = x.begin(); 52 for(iterSum;iterSum != x.end();iterSum++) 53 { 54 sum += iterSum->second*stamp[iterSum->first]; 55 } 56 if(t>=4 || sum >= m) 57 {//最多4张邮票,即树的高度最大为4 58 //进行结果的判断及赋值 59 if(sum == m) 60 {//可能是bestx 61 //计算邮票种类数 62 int Typ = x.size(); 63 //计算邮票张数 64 int Count = 0; 65 map<int,int>::iterator iter = x.begin(); 66 for(iter;iter != x.end();iter++) 67 { 68 Count += iter->second; 69 } 70 ///1.邮票种类数多为best 71 if(Typ>bestTyp) 72 {//进行更新 73 UpDate(Count,Typ); 74 }else if(Typ == bestTyp&&Count<bestp)///2.如果邮票种类数相等,张数小的为best 75 { 76 UpDate(Count,Typ); 77 }else if(Typ == bestTyp&&Count == bestp) 78 {///3.种数相同,张数相同,有最大面值的为best;否则tie,最优解的个数++ 79 map<int,int>::iterator iter1 = x.end();iter1--; 80 map<int,int>::iterator iter2 = bestx.end();iter2--; 81 if(iter1->first > iter2->first) 82 { 83 UpDate(Count,Typ); 84 }else if(iter1->first == iter2->first){ 85 bestCount ++; 86 } 87 } 88 } 89 return; 90 } 91 else{ 92 for(int i = pre;i<n;i++) 93 {//第t张邮票面值为i 94 ++x[i];///将面值i的邮票插入map,并将计数++ 95 BackTrack(t+1,n,m,i); 96 x[i]--;///进行回溯 97 if(x[i] <= 0) 98 { 99 x.erase(i); 100 } 101 } 102 } 103 } 104 105 int main() 106 { 107 int types = 0; 108 while(scanf("%d",&types) != EOF) 109 { 110 int n = 0;//邮票的种类数 111 while(types) 112 { 113 stamp[n++] = types; 114 if(scanf("%d",&types) == EOF) 115 return 0; 116 } 117 int m = 0; 118 cin>>m; 119 while(m) 120 { 121 BackTrack(0,n,m,0); 122 123 PrintAns(m); 124 bestx.clear(); 125 x.clear(); 126 bestp=0;//用来记录最优解邮票的张数 127 bestTyp = 0;//用来记录最优解邮票的种数 128 bestCount = 0; 129 cin>>m; 130 } 131 } 132 133 134 135 return 0; 136 }