POJ3513 Let's Go to the Movies

本文解决了一个关于家庭成员看电影时如何购买个人票与家庭票才能达到最优价格的问题。通过离散化姓名并构建父子关系树,利用树形DP算法确定最佳购票方案。
  POJ3513 Let's Go to the Movies
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 1736Accepted: 429

Description

3513_1.pngA favorite pastime for big families in Acmestan is going to the movies. It is quite common to see a number of these multi-generation families going together to watch a movie. Movie theaters in Acmestan have two types of tickets: A single ticket is for exactly one person while a family ticket allows a parent and their children to enter the theater. Needless to say, a family ticket is always priced higher than a single ticket, sometimes as high as five times the price of a single ticket.

It is quite challenging for families to decide which ticket arrangement is most economical to buy. For example, the family depicted in the figure on the right has four ticket arrangements to choose from: Seven single tickets; Two family tickets; One family ticket (for adam,bobcindy) plus four single tickets for the rest; Or, one family ticket (for bob and his four children) plus single tickets for the remaining two.

Write a program to determine which ticket arrangement has the least price. If there are more than one such arrangement, print the arrangement that has the least number of tickets.

Input

Your program will be tested on one or more test cases. The first line of each test case includes two positive integers (S and F) where S is the price of a single ticket and F is the price of a family ticket. The remaining lines of the test case are either the name of a person going by him/herself, or of the form:

N1 N2 N3 … Nk

where N1 is the name of a parent, with N2… Nk being his/her children. Names are all lower-case letters, and no longer than 1000 characters. No parent will be taking more than 1000 of their children to the movies :-). Names are unique, the name of a particular person will appear at most twice: Once as a parent, and once as a child. There will be at least one person and at most 100,000 people in any test case.

The end of a test case is identified by the beginning of the following test case (a line made of two integers.) The end of the last test case is identified by two zeros.

Output

For each test case, write the result using the following format:

k. NS NF T

Where k is the test case number (starting at 1), NS is the number of single tickets, NF is the number of family tickets, and T is the total cost of tickets.

Sample Input

1 3
adam bob cindy
bob dima edie fairuz gary
1 2
john
paul
george
ringo
1 3
a b c
0 0

Sample Output

1. 2 1 5
2. 4 0 4
3. 0 1 3

Source

******************************************************************************
题目大意:ben1222说这道题是“多细胞看电影”,我笑翻了。题目的意思是,有一户家庭去看电影,看电影可以买家庭票也可以买个人票,个人票的票价总比家庭票的票价低。家庭票只能由父亲或者母亲买,只能带领ta的儿子去看,也就是如果有三代人去看电影,至少要买两张家庭票。现在问怎么买票比较合算,以及如果有多种情况买到最合算的票时,需要票数张数最少的那个组合。
解题思路:第一句话:从来没看见过这么恶心的输入,出题人那个叫大坑爹啊!我还被逼用了sscanf,从来没用过,汗!回归正题。当输入完后就需要把这些个人名离散化,当然用map就够了。离散化后根据直系关系就形成了一棵树,然后就是树形dp。每个节点有两个状态:0是该节点还没被覆盖,即这个根的父亲一定要卖家庭票;1表示这个节点已经买过票了。
#include <stdio.h>
#include <string>
#include <string.h>
#include <iostream>
#include <vector>
#include <map>
#define N 100005
using namespace std;

vector<long long>gra[N];
map<string,long long>hash;
string nam;
char str[1000*2000+5];
long long s,f,vis[N],id;
struct Dp
{
    long long ns,nf;
}dp[N][2];

void dfs(long long r)
{
    vis[r]=1;
    Dp temp;
    dp[r][1].nf=1;
    for(long long i=0;i<gra[r].size();i++)
    {
        long long t=gra[r][i];
        dfs(t);
        long long a=s*dp[t][0].ns+f*dp[t][0].nf;
        long long b=s*dp[t][1].ns+f*dp[t][1].nf;
        if(a>b||(a==b&&dp[t][1].nf>dp[t][0].nf))
        {
            dp[r][1].ns+=dp[t][1].ns;
            dp[r][1].nf+=dp[t][1].nf;
        }
        else
        {
            dp[r][1].ns+=dp[t][0].ns;
            dp[r][1].nf+=dp[t][0].nf;
        }
        dp[r][0].ns+=dp[t][1].ns;
        dp[r][0].nf+=dp[t][1].nf;
    }
    long long a=s*dp[r][0].ns+s+f*dp[r][0].nf;
    long long b=s*dp[r][1].ns+f*dp[r][1].nf;
    if(a<b||(a==b&&dp[r][0].nf>dp[r][1].nf))
    {
        dp[r][1].ns=dp[r][0].ns+1;
        dp[r][1].nf=dp[r][0].nf;
    }

}

void run(long long h)
{
    Dp ans;
    ans.nf=ans.ns=0;
    for(long long i=1;i<id;i++)
        if(vis[i]==0)
        {
            dfs(i);
            ans.nf+=dp[i][1].nf;
            ans.ns+=dp[i][1].ns;
        }
    printf("%lld. %lld %lld %lld\n",h,ans.ns,ans.nf,s*ans.ns+f*ans.nf);
}

int main()
{
    gets(str);
    for(long long h=1;;h++)
    {
        sscanf(str,"%lld%lld",&s,&f);
        if(s==0&f==0)break;
        id=1;
        for(long long i=0;i<N;i++)
            gra[i].clear();
        hash.clear();
        memset(dp,0,sizeof(dp));
        memset(vis,0,sizeof(vis));
        while(1)
        {
            gets(str);
            if(str[0]>='0'&&str[0]<='9')break;
            if(!(str[0]>='a'&&str[0]<='z'))continue;
            long long flag=0,k=0,len=strlen(str),fa;
            char temp[1005];
            for(long long i=0;i<=len;i++)
            {
                if(i==len||str[i]==' ')
                {
                    temp[k]=0;
                    k=0;
                    nam=temp;
                    if(hash.count(nam)==0)hash[nam]=id++;
                    if(flag==0)
                        flag=1,fa=hash[nam];
                    else
                        gra[fa].push_back(hash[nam]),vis[hash[nam]]=1;
                    continue;
                }
                temp[k++]=str[i];
            }
        }
        run(h);
    }
}

  

转载于:https://www.cnblogs.com/Fatedayt/archive/2011/09/26/2192158.html

一、数据采集层:多源人脸数据获取 该层负责从不同设备 / 渠道采集人脸原始数据,为后续模型训练与识别提供基础样本,核心功能包括: 1. 多设备适配采集 实时摄像头采集: 调用计算机内置摄像头(或外接 USB 摄像头),通过OpenCV的VideoCapture接口实时捕获视频流,支持手动触发 “拍照”(按指定快捷键如Space)或自动定时采集(如每 2 秒采集 1 张),采集时自动框选人脸区域(通过Haar级联分类器初步定位),确保样本聚焦人脸。 支持采集参数配置:可设置采集分辨率(如 640×480、1280×720)、图像格式(JPG/PNG)、单用户采集数量(如默认采集 20 张,确保样本多样性),采集过程中实时显示 “已采集数量 / 目标数量”,避免样本不足。 本地图像 / 视频导入: 支持批量导入本地人脸图像文件(支持 JPG、PNG、BMP 格式),自动过滤非图像文件;导入视频文件(MP4、AVI 格式)时,可按 “固定帧间隔”(如每 10 帧提取 1 张图像)或 “手动选择帧” 提取人脸样本,适用于无实时摄像头场景。 数据集对接: 支持接入公开人脸数据集(如 LFW、ORL),通过预设脚本自动读取数据集目录结构(按 “用户 ID - 样本图像” 分类),快速构建训练样本库,无需手动采集,降低系统开发与测试成本。 2. 采集过程辅助功能 人脸有效性校验:采集时通过OpenCV的Haar级联分类器(或MTCNN轻量级模型)实时检测图像中是否包含人脸,若未检测到人脸(如遮挡、侧脸角度过大),则弹窗提示 “未识别到人脸,请调整姿态”,避免无效样本存入。 样本标签管理:采集时需为每个样本绑定 “用户标签”(如姓名、ID 号),支持手动输入标签或从 Excel 名单批量导入标签(按 “标签 - 采集数量” 对应),采集完成后自动按 “标签 - 序号” 命名文件(如 “张三
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值