转载: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. 徐州赛区网络预赛 D Easy Math

    比赛快结束的适合看了一下D题,发现跟前几天刚刚做过的HDU 5728 PowMod几乎一模一样,当时特兴奋,结果一直到比赛结束都一直WA.回来仔细一琢磨才发现,PowMod这道题保证了n不含平方因子, ...

  2. 使用nodejs + wecharty打造你的个人微信机器人

    开源地址:https://github.com/isnl/wechat-robot 注: 从2017年6月下旬开始,使用基于web版微信接入方案存在大概率的被限制登陆的可能性. 主要表现为:无法登陆W ...

  3. chrome清除缓存、不使用缓存而刷新快捷键

    Ctrl+Shift+Del  清除Google浏览器缓存的快捷键 Ctrl+Shift+R  重新加载当前网页而不使用缓存内容 转载于:https://www.cnblogs.com/JAVA-ST ...

  4. Jenkins 部署(基于 windows)

    一.安装 jdk,配置环境变量 二.安装 tomcat 和 jenkins 1.检查电脑上 8080 端口是否被占用: 命令行中输入:netstat -ano 2.下载Tomcat Tomcat官方网 ...

  5. js循环数组方法some和forEach怎么用

    forEach不支持break和return.一般普通循环都是用forEach ar arr1=["aa","bb","aa"," ...

  6. Flutter 标签类控件大全Chip

    老孟导读:Flutter内置了多个标签类控件,但本质上它们都是同一个控件,只不过是属性参数不同而已,在学习的过程中可以将其放在放在一起学习,方便记忆. RawChip Material风格标签控件,此 ...

  7. Qt之分模块log

    说明 对于一般的log,使用 qInstallMessageHandler 重定向到文件即可,甚至可以根据日志等级,分类存储.但是并不是适用所有情况,比如,程序运行时动态创建模块,而每个模块需要创建不 ...

  8. 如何得知某期刊是否被EI收錄?

    转载:http://tul.blog.ntu.edu.tw/archives/4627 若因投稿或評鑑需要,欲得知某期刊是否被 EI 收錄,其實就是確認該期刊是否包含在 EV 平台中的 COMPEND ...

  9. xml(3)

    xml的解析方式:dom解析和sax解析 DOM解析 使用jaxp进行增删改查 1.创建DocumentBuilderFactory工厂 2.通过DocumentBuilderFactory工厂创建D ...

  10. 预测算法:基于UCF的电影推荐算法

    #基于用户的推荐类算法 from math import sqrt #计算两个person的欧几里德距离 def sim_distance(prefs,person1,person2): si = { ...