【DFS】STAMPS

[Poj1010]STAMPS
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 18867   Accepted: 5469

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. 

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.

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. 

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

 

题目大意:给你一些邮票,有一些个客户,你要用不超过4张邮票组成这个面值,优先级如下:

               ①种类最多者优先

               ②①一样的情况下票数最多者优先

               ③①②一样的情况下最大的面值最大优先

               ④以上都一样(最优答案超过一种),即输出tie

               ⑤如果没有方案:none

 

试题分析:据说数据有些坑人,大家开100的数组就足够了。

               直接加一些剪枝,判优,更新答案等乱七八糟的东西就够了

 

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
//#include<cmath>

using namespace std;
const int INF = 9999999;
#define LL long long

inline int read(){
	int x=0,f=1;char c=getchar();
	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
	for(;isdigit(c);c=getchar()) x=x*10+c-'0';
	return x*f;
}
int N,M;
int a[100001];
int Q;
int ans[5],tmp[5];
int anss,ansx,ansd;
bool tie=false,flag=false;

void copy(int st,int tmpx,int l){//复制到答案中
	anss=st;ansd=l;ansx=tmpx;
	for(int i=1;i<=st;i++) ans[i]=tmp[i];
	return ;
}

bool cmp(int st,int tmpx,int l){//比较优先
	if(l>ansd) {tie=false;return true;}
	if(l<ansd) {return false;}
	if(anss<st) {tie=false;return true;}
	if(anss<st) {return false;}
	if(ansx<tmpx) {tie=false;return true;}
	if(ansx>tmpx) {return false;}
	if(l==ansd&&anss==st&&ansx==tmpx) tie=true;
	return false;
}

void DFS(int sum,int step,int now,int tmpx,int l){
        //sum总面值 step步数 now现在可以访问的最小编号 tmpx搜索时选择的最大元素 l种数
	if(sum>Q||step>4||sum+(4-step)*a[N]<Q) return ;//剪枝
	if(sum==Q){
		flag=true;
		if(cmp(step,tmpx,l)) copy(step,tmpx,l);
		return ;
	}
	for(int i=now;i<=N;i++){
		if(i==0) continue;
    	tmp[step+1]=a[i];
	    if(i==now) DFS(sum+a[i],step+1,i,max(tmpx,a[i]),l);
	    else DFS(sum+a[i],step+1,i,max(tmpx,a[i]),l+1);
	}
	return ;
}

int p;

int main(){
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	while(scanf("%d",&p)!=EOF){
		a[++N]=p;
		while(a[N]!=0) a[++N]=read();
		N--;
		sort(a+1,a+N+1);//排序!
		Q=read();
		while(Q){
			memset(ans,0,sizeof(ans));
			memset(tmp,0,sizeof(tmp));
			tie=false;
			flag=false;
			anss=0,ansd=0,ansx=0;
			DFS(0,0,0,0,0);
			if(!flag) {cout<<Q,puts(" ---- none");Q=read();continue;}
			if(tie) {printf("%d (%d): ",Q,ansd);puts("tie");Q=read();continue;} 
			printf("%d (%d): ",Q,ansd);
			for(int i=1;i<anss;i++)
		   		printf("%d ",ans[i]);
			printf("%d
",ans[anss]);
			Q=read();
		}
		N=0;
    }
	return 0;
}
原文地址:https://www.cnblogs.com/wxjor/p/7002868.html