POJ1010(dfs)

题目意思就是,给你一些邮票,要组合出K面值的,优先级:组成种类尽可能多>所需邮票数尽可能少>最大面值尽可能大。如果都相等,那么就输出tie。

这题目我一开始一直在想怎么可以用一个优秀的姿势在dfs的过程中满足上述要求第筛选…发现号困难,最后看大神的题解了。心碎。

/*************************************************************************
	> OS     : Linux 3.2.0-60-generic #91-Ubuntu
	> Author : yaolong
	> Mail   : [email protected]
	> Created Time: 2014年05月23日 星期五 07:58:23
 ************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int a[100];  //存邮票
int v[100];  //数目
int cnt[100];//用于读取时候筛选同一币值超过5的
bool is_tie,first; //是否平局,和第一次得出结果标志
int res[6];       //结果
int best_res[6];  //最佳结果,0,5两个位置分别记录多少张和多少种
int a_i;          //邮票的数目
void set_res(int num,int type){
    best_res[0]=num;
    best_res[5]=type;
    for(int i=1;i<5;i++){
        best_res[i]=res[i];
    }
}
int get_max (int *s){
    return max(max(s[1],s[2]),max(s[3],s[4]));
}
void dfs(int need,int num,int type,int pre){

    if(num>4){
       return ;
    }
    if(need==0){
        if(first){
            first=0;
            set_res(num,type);
        }else{
               if(type==best_res[5]){
                   if(num==best_res[0]){

                       int a=get_max(res);
                       int b=get_max(best_res);
                       if(a==b){
                           is_tie=1;
                       }else if(a>b){
                           is_tie=0;
                           set_res(num,type);
                       }
                   }else{
                       if(num<best_res[0])
                       {
                           is_tie=0;
                           set_res(num,type);
                       }
                   }
               }else if(type>best_res[5]){
                   is_tie=0;
                   set_res(num,type);
               }
        }
        return ;
    }
    for(int i=pre;i<a_i;i++){
        if(need>=a[i]){
            res[num+1]=a[i];
            if(v[i]!=0){
                v[i]++;
                dfs(need-a[i],num+1,type,i);
            }else{
                v[i]++;
                dfs(need-a[i],num+1,type+1,i);
            }
            res[num+1]=0;
            v[i]--;
        }else return;
    }

}
int main(){
    for(;;){
        memset(cnt,0,sizeof(cnt));
        a_i=0;
        int tmp;
        for(;;){
            if(scanf("%d",&tmp)==EOF){
                return 0;
            }
            if(tmp==0){
                break;
            }
            if(cnt[tmp]<5){
                cnt[tmp]++;
                a[a_i++]=tmp;
            }
        }
        sort(a,a+a_i);

        while(scanf("%d",&tmp)&&tmp){
            memset(v,0,sizeof(v));
            memset(res,0,sizeof(res));
            memset(best_res,0,sizeof(best_res));
            first=true;is_tie=false;
            dfs(tmp,0,0,0);
            if(first){   //无解
                printf("%d ---- none",tmp);
            }else{
                if(is_tie){  //平
                    printf("%d (%d): tie",tmp,best_res[5]);
                }else{
                    printf("%d (%d):",tmp,best_res[5]);
                    for(int i=1;i<5;i++){
                        if(best_res[i])
                        printf(" %d",best_res[i]);
                    }   

                }
            }
            puts("");

        }
    }

    return 0;
}

POJ1010(dfs),布布扣,bubuko.com

时间: 2024-10-12 07:25:24

POJ1010(dfs)的相关文章

【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 s

解救小哈——DFS算法举例

一.问题引入 有一天,小哈一个人去玩迷宫.但是方向感不好的小哈很快就迷路了.小哼得知后便去解救无助的小哈.此时的小哼已经弄清楚了迷宫的地图,现在小哼要以最快的速度去解救小哈.那么,问题来了... 二.问题的分析 首先我们用一个二维数组来存储这个迷宫,刚开始的时候,小哼处于迷宫的入口处(1,1),小哈在(p,q).其实这道题的的本质就在于找从(1,1)到(p,q)的最短路径. 此时摆在小哼面前的路有两条,我们可以先让小哼往右边走,直到走不通的时候再回到这里,再去尝试另外一个方向. 在这里我们规定一

【BZOJ4942】[Noi2017]整数 线段树+DFS(卡过)

[BZOJ4942][Noi2017]整数 题目描述去uoj 题解:如果只有加法,那么直接暴力即可...(因为1的数量最多nlogn个) 先考虑加法,比较显然的做法就是将A二进制分解成log位,然后依次更新这log位,如果最高位依然有进位,那么找到最高位后面的第一个0,将中间的所有1变成0,那个0变成1.这个显然要用到线段树,但是复杂度是nlog2n的,肯定过不去. 于是我在考场上yy了一下,这log位是连续的,我们每次都要花费log的时间去修改一个岂不是很浪费?我们可以先在线段树上找到这段区间

uva1103(dfs)

UVA - 1103 还是没写好,,看的别人的 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 #include <cstdlib> 7 #include <stack> 8 #include <cctype> 9 #include <str

poj 1088 滑雪 DP(dfs的记忆化搜索)

题目地址:http://poj.org/problem?id=1088 题目大意:给你一个m*n的矩阵 如果其中一个点高于另一个点 那么就可以从高点向下滑 直到没有可以下滑的时候 就得到一条下滑路径 求最大的下滑路径 分析:因为只能从高峰滑到低峰,无后效性,所以每个点都可以找到自己的最长下滑距离(只与自己高度有关).记忆每个点的最长下滑距离,当有另一个点的下滑路径遇到这个点的时候,直接加上这个点的最长下滑距离. dp递推式是,dp[x][y] = max(dp[x][y],dp[x+1][y]+

蓝桥杯 大臣的旅费_树的最长度_两次DFS

#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <functional> #include <vector> using namespace std; const int maxn = 1000000 + 10; const int INF = 10000000

A. The Fault in Our Cubes 暴力dfs

http://codeforces.com/gym/101257/problem/A 把它固定在(0,0, 0)到(2, 2, 2)上,每次都暴力dfs检查,不会超时的,因为规定在这个空间上,一不行,就会早早退出. 这样写起来比较好写. #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <

codeforces717E Paint it really, really dark gray(树上dfs)

题意: 给你一棵树,2e5个节点,每个节点有一种颜色(黑色或粉色) 让你从节点1开始,自由沿边行走,到达节点时会把这个节点的颜色改变 要求你输出任意一条路径使得从节点1出发,所有节点的颜色都变为黑色 思路: 很明显要递归遍历 每到达一个节点就先改变节点的颜色标志并输出当前节点 如果当前到达了叶子节点,则不用进行操作 返回上层节点时再改变节点的颜色标志并输出当前节点,然后判断叶子节点的颜色,如果为粉色,则再到达一次叶子节点再回到当前节点 这样确保当前节点的所有儿子节点都为黑色的 然后就这样一直递归

POJ2488 dfs

A Knight's Journey Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 41972   Accepted: 14286 Description Background The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey ar