http://poj.org/problem?id=1010 (题目链接)
感到了英语深深的恶意。。。
题意(真的很难懂。。。。)
第一行数字是邮票的面值,每一个数字就是一个不同的种类,哪怕面值相同。以0结束。第二行数字是顾客所需要的邮票总面值。每个数字就是一个顾客的需求,以0结束。每两行是一组case。顾客是集邮爱好者,所以你必须尽可能的给他不同种类的邮票。但是一位顾客最多只能拿4张邮票。显然,我们拥有的邮票就是第一行中的数据。
关于tie:
满足顾客需求的解就是可行解。
邮票种类最多的可行解为最优。
如果存在两个以上的最优解的邮票种类是一样的,张数最少的更优
张数也一样的话,这些最优解中最大面值较大的更优。
若邮票种类、张数、最大面值三者都分别相同,则认为这些最优解相同,输出tie。
没有解就是none。
Solution
这不就是裸的dfs吗。。加几个可行性剪枝就可以轻松过了。
代码
// poj1010 #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<set> #define MOD 1000000007 #define inf 2147483640 #define LL long long #define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout); using namespace std; inline LL getint() { LL x=0,f=1;char ch=getchar(); while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=10010; int a[maxn],ans[maxn],t[maxn],b[maxn],vis[maxn]; int n,m,flag; void work3() { int t1=0,t2=0; for (int i=1;i<=4;i++) { t1=max(a[t[i]],t1); t2=max(a[ans[i]],t2); } if (t1>t2) {flag=3;for (int i=0;i<=n;i++) ans[i]=t[i];} else if (t1==t2) flag=4; } void work2() { int t1=4,t2=4; for (int i=1;i<=4;i++) { if (t[i]==0) t1--; if (ans[i]==0) t2--; } if (t1<t2) {flag=2;for (int i=0;i<=n;i++) ans[i]=t[i];} else if (t1==t2) work3(); } void work1() { t[0]=0; for (int i=1;i<=n;i++) vis[i]=0; for (int i=1;i<=4;i++) if (t[i] && !vis[t[i]]) {vis[t[i]]=1;t[0]++;} if (ans[0]<t[0]) {flag=1;for (int i=0;i<=4;i++) ans[i]=t[i];} else if (ans[0]==t[0]) work2(); } void dfs(int x,int p,int w,int W) { if (x==5) { if (w==W) work1(); return; } if (w>=W || w+(4-x+1)*a[n]<W) return; for (int i=p;i<=n;i++) { t[x]=i; dfs(x+1,i,w+a[i],W); } } int main() { while (1) { n=m=1; while (scanf("%d",&a[n])!=EOF && a[n]) n++; if (n==1) break; n--; while (scanf("%d",&b[m])!=EOF && b[m]) m++; m--; sort(a+1,a+1+n); for (int i=1;i<=m;i++) { for (int j=0;j<=4;j++) ans[j]=0; printf("%d ",b[i]); flag=0; dfs(1,0,0,b[i]); if (flag==4) printf("(%d): tie ",ans[0]); else if (flag==0) printf("---- none "); else { printf("(%d):",ans[0]); for (int i=1;i<=4;i++) if (ans[i]) printf(" %d",a[ans[i]]); printf(" "); } } } return 0; }