转载:http://www.cnblogs.com/Asm-Definer/p/4372749.html

1021: [SHOI2008]Debt 循环的债务

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 985  Solved: 513
[Submit][Status][Discuss]

Description

  Alice、Bob和Cynthia总是为他们之间混乱的债务而烦恼,终于有一天,他们决定坐下来一起解决这个问题。
不过,鉴别钞票的真伪是一件很麻烦的事情,于是他们决定要在清还债务的时候尽可能少的交换现金。比如说,Al
ice欠Bob 10元,而Cynthia和他俩互不相欠。现在假设Alice只有一张50元,Bob有3张10元和10张1元,Cynthia有3
张20元。一种比较直接的做法是:Alice将50元交给Bob,而Bob将他身上的钱找给Alice,这样一共就会有14张钞票
被交换。但这不是最好的做法,最好的做法是:Alice把50块给Cynthia,Cynthia再把两张20给Alice,另一张20给
Bob,而Bob把一张10块给C,此时只有5张钞票被交换过。没过多久他们就发现这是一个很棘手的问题,于是他们找
到了精通数学的你为他们解决这个难题。

Input

  输入的第一行包括三个整数:x1、x2、x3(-1,000≤x1,x2,x3≤1,000),其中 x1代表Alice欠Bob的钱(如
果x1是负数,说明Bob欠了Alice的钱) x2代表Bob欠Cynthia的钱(如果x2是负数,说明Cynthia欠了Bob的钱) x3
代表Cynthia欠Alice的钱(如果x3是负数,说明Alice欠了Cynthia的钱)
接下来有三行
每行包括6个自然数:
a100,a50,a20,a10,a5,a1
b100,b50,b20,b10,b5,b1
c100,c50,c20,c10,c5,c1
a100表示Alice拥有的100元钞票张数,b50表示Bob拥有的50元钞票张数,以此类推。
另外,我们保证有a10+a5+a1≤30,b10+b5+b1≤30,c10+c5+c1≤30,而且三人总共拥有的钞票面值总额不会
超过1,000。

Output

  如果债务可以还清,则输出需要交换钞票的最少张数;如果不能还清,则输出“impossible”(注意单词全部
小写,输出到文件时不要加引号)。

Sample Input

输入一
10 0 0
0 1 0 0 0 0
0 0 0 3 0 10
0 0 3 0 0 0
输入二
-10 -10 -10
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0

Sample Output

输出一
5
输出二
0
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=,INF=0x3f3f3f3f,val[]={,,,,,};
int cnt[][],tot[],Cur[],Tar[],Sum,f[][maxn][maxn];//f开三维,第一位滚动数组用,第二第三维则是A,B所拥有的钱的数目,因为A,B确定,C一定确定,所以不需要开第四维
inline void init(){
    int a,b,c;
    scanf("%d%d%d",&a,&b,&c);
    for(int i=;i<;++i) for(int j=;j>=;--j){
        scanf("%d",&cnt[i][j]);
        Cur[i]+=cnt[i][j]*val[j];
        tot[j]+=cnt[i][j];
    }
    Sum=Cur[]+Cur[]+Cur[];
    Tar[]=Cur[]-a+c;//A的目标钱数
    Tar[]=Cur[]-b+a;//B的目标钱数
    if(Tar[]<||Tar[]<||Sum-Tar[]-Tar[]<) {
        puts("impossible");
        exit();
    }
}
int main(){
    init();
    const int rang=Sum+;
    int i,j,k,a,b,t,tmp,da,db,cnta,cntb;
    bool cur,las;
    for(i=;i<=Sum;++i)
        memset(f[][i],0x3f,sizeof(int)*rang);
    f[][Cur[]][Cur[]]=;
    for(i=;i<;++i) {
        cur=i&,las=cur^;
        for(j=;j<=Sum;++j) memset(f[cur][j],0x3f,sizeof(int)*rang);
        for(j=;j<=Sum;++j){//这里枚举的方向无所谓
            t=Sum-j;
            for(k=;k<=t;++k) {
                if(f[las][j][k]==INF) continue;
                f[cur][j][k]=min(f[cur][j][k],f[las][j][k]);
                for(a=;a<=tot[i];++a) {//枚举第i种钱的数目在A中的个数
                    tmp=tot[i]-a;
                    for(b=;b<=tmp;++b){//枚举第i种钱的数目在B中的个数
                        da=a-cnt[][i],db=b-cnt[][i];//da是交换时A所用的第i种钱的数目,db是B所用的。。
                        cnta=j+da*val[i],cntb=k+db*val[i];
                        if(cnta<||cntb<) continue;
                        f[cur][cnta][cntb]=min(f[cur][cnta][cntb],f[las][j][k]+(abs(da)+abs(db)+abs(da+db))/);//因为交易的话不会出现传递式的交易(就是同一个钱币A->B->C,可以直接A->C,所以的话如果da,db正负相同肯定OK啦(此时A,B均是给C,或C给他俩没有彼此交易),如果不同的话只能说明A,B有彼此交易,那么会算重一部分的。
                    }
                }
            }
        }
    }
    if(f[cur][Tar[]][Tar[]]==INF) puts("impossible");
    else printf("%d\n",f[cur][Tar[]][Tar[]]);
}

BZOJ1021的更多相关文章

  1. 【BZOJ1021】[SHOI2008]循环的债务(动态规划)

    [BZOJ1021][SHOI2008]循环的债务(动态规划) 题面 BZOJ 洛谷 题解 感觉以前的题目都好小清新啊,我这种智商丢失的选手完全写不动. 这题看着就像一个\(dp\),并且我们发现每种 ...

  2. bzoj1021 [SHOI2008]Debt 循环的债务

    前天打了一场比赛,让我知道自己Dp有多弱了,伤心了一天,没刷bzoj. 昨天想了一天,虽然知道几何怎么搞,但我还是不敢写,让我知道自己几何有多弱了,伤心了一天,没刷bzoj 1021: [SHOI20 ...

  3. bzoj千题计划111:bzoj1021: [SHOI2008]Debt 循环的债务

    http://www.lydsy.com/JudgeOnline/problem.php?id=1021 如果A收到了B的1张10元,那么A绝对不会把这张10元再给C 因为这样不如B直接给C优 由此可 ...

  4. BZOJ1021 [SHOI2008]循环的债务

    Description Alice.Bob和Cynthia总是为他们之间混乱的债务而烦恼,终于有一天,他们决定坐下来一起解决这个问题. 不过,鉴别钞票的真伪是一件很麻烦的事情,于是他们决定要在清还债务 ...

  5. BZOJ1021 SHOI2008循环的债务

    dp模拟即可. d[i][j][k]表示使用前i种面值,1号手里钱为j,2号手里钱为k时最少操作数 使用滚动数组压缩空间 #include <cstdio> #include <cs ...

  6. [bzoj1021][SHOI2008]Debt 循环的债务 (动态规划)

    Description Alice. Bob和Cynthia总是为他们之间混乱的债务而烦恼,终于有一天,他们决定坐下来一起解决这个问题.不过,鉴别钞票的真伪是一件很麻烦的事情,于是他 们决定要在清还债 ...

  7. bzoj题解汇总(1021~1031)

    bzoj1021:普通dp bzoj1022:裸的Anti-Nim 必胜:①sg=0且所有不超过1 ②sg>1且存在至少一个超过1 bzoj1023:http://www.cnblogs.com ...

  8. SHOI2008 题目总结

    感觉还是上海人出题水平高?这套题写得心旷神怡的...总之很难就是啦 由于我实在不适应博客园这种排版和字体..所以我的文章可能会特别难看大家见谅..说不定回头开发一个支持全局LaTeX的博客也不错?23 ...

  9. BZOJ第1页养成计划

    嗯,用这篇博客当一个目录,方便自己和学弟(妹?)们查阅.不定期更新. BZOJ1000   BZOJ1001   BZOJ1002   BZOJ1003   BZOJ1004   BZOJ1005   ...

随机推荐

  1. Swoole 实战:MySQL 查询器的实现(协程连接池版)

    目录 需求分析 使用示例 模块设计 UML 类图 入口 事务 连接池 连接 查询器的组装 总结 需求分析 本篇我们将通过 Swoole 实现一个自带连接池的 MySQL 查询器: 支持通过链式调用构造 ...

  2. Redis介绍及字符串操作

    一.前言 不同程序之间实现通信的方法? A.通过不同程序之间建立socket,实现通信.实际应用适用于使用broker,如RabbitMQ,ZeroMQ. B.通过Json,Pickle,利用文件的写 ...

  3. Linux命令(4):touch

    功能说明: touch命令参数可创建新文件以及更改文档或目录的日期时间,包括存取时间和更改时间. 命令格式: touch [选项]... 文件... 命令参数: -a   或--time=atime或 ...

  4. Get史上最优雅的加密方式!没有之一!

    你的配置文件是不是还在使用下面这种落后的配置暴露一些密码: jdbc.url=jdbc:mysql://127.0.0.1:3305/afei jdbc.username=afei 如果是,那么继续往 ...

  5. 在TX2上多线程读取视频帧进行caffe推理

    参考文章:Multi-threaded Camera Caffe Inferencing TX2之多线程读取视频及深度学习推理 背景 一般在TX2上部署深度学习模型时,都是读取摄像头视频或者传入视频文 ...

  6. python(简介)

    python发展史: 自从20世纪90年代初Python语言诞生至今,它已被逐渐广泛应用于系统管理任务的处理和Web编程. Python的创始人为荷兰人吉多·范罗苏姆 [3]  (Guido van ...

  7. centos安装libconfig

    安装很简单,生成的.so文件会被安装到/usr/local/lib目录,记得修改/etc/profile. 安装过程会出现两个错误: What is makeinfo, and how do I ge ...

  8. I - Union 2019ccpc女生赛

    I - Union 这是2019女生赛最难的一个题目,但是现在去写,我觉得没有想象之中的那么难. 把这个题目分成几个部分来考虑. 假设给你k个数,让你分成三个集合,满足这四个条件,且不需要考虑时间和空 ...

  9. dp (1)

    D - Tree of Tree ZOJ - 3201 这个题目我开始是这么定义的dp[i][j][0] dp[i][j][1] 表示对于第i个节点还有j个的选择 0 代表不选这个节点,1 代表选这个 ...

  10. (2).mybatis单元测试(junit测试)

    一.Junit使用步骤:1.创建测试目录,(src.测试目录是test)2.在测试目录test中创建与src中相同的包名3.为需要测试的类创建测试类,例如:UsersMapper,测试类是UsersM ...