[bzoj1021][SHOI2008]Debt 循环的债务 (动态规划)
Description
Alice、 Bob和Cynthia总是为他们之间混乱的债务而烦恼,终于有一天,他们决定坐下来一起解决这个问题。不过,鉴别钞票的真伪是一件很麻烦的事情,于是他 们决定要在清还债务的时候尽可能少的交换现金。比如说,Alice欠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
HINT
对于100%的数据,x1、x2、x3 ≤ |1,000|。
分析
唔……好像没什么难的吧,设f(i,j)表示从初始状态到“A手中持有i元,B手中持有j元,C手中持有Sum-i-j元”这一状态需要的最少操作数,然后dp即——
——等等……这里转移方向是加减两个方向都可以啊?不可能是dp吧……?
于是我就在网上看了巨神们的题解……
啊……看来又是我蠢了……
他们的思路大概是这样的……考虑这样一个事实:对于同样一种面值的纸币,最优解中不可能出现“A给B,B给C”这样的循环交付,否则我们只要让A直接给C就可以得到更优的解。于是我们就可以从面值来枚举,对每种面值分别dp更新答案。
代码应该也比较好懂吧,只不过我写得似乎太冗长了……

#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cctype>
#include <algorithm>
template< x = ch - - }
, INF = ] = {, , , , , };
][], tot[], Cur[], Tar[], Sum, f[][maxn][maxn]; inline getd(a), getd(b), getd(c);
;i < ;++i);j >= ;--j){
getd(cnt[i][j]);
Cur[i] += cnt[i][j] * val[j];
tot[j] += cnt[i][j];
}
Sum = Cur[] + Cur[] + Cur[];
Tar[] = Cur[] - a + c;
Tar[] = Cur[] - b + a;
] < || Tar[] < || Sum - Tar[] - Tar[] < ){
printf( exit();
}
}
#include <cmath>
inline ;
;i <= Sum;++i)memset(f[][i], f[][Cur[]][Cur[]] = ;
;i < ;++i){ , las = cur ^ ;
;j <= Sum;++j)memset(f[cur][j], ;j <= Sum;++j){
t = Sum - j;
;k <= t;++k){ UPD(f[cur][j][k], f[las][j][k]);
;a <= tot[i];++a){
tmp = tot[i] - a;
;b <= tmp;++b){ ][i], db = b - cnt[][i];
cnta = j + da * val[i], cntb = k + db * val[i];
|| cntb < || cnta + cntb > Sum) UPD(f[cur][cnta][cntb], f[las][j][k] + (abs(da) + abs(db) + abs(da + db)) / );
}
}
}
}
}
]][Tar[]] == INF)printf( ]][Tar[]]);
}
#ifdef DEBUG
freopen( freopen( freopen( init();
work();
#ifdef DEBUG
printf( ;
}
动态规划
[bzoj1021][SHOI2008]Debt 循环的债务 (动态规划)的更多相关文章
- bzoj1021 [SHOI2008]Debt 循环的债务
前天打了一场比赛,让我知道自己Dp有多弱了,伤心了一天,没刷bzoj. 昨天想了一天,虽然知道几何怎么搞,但我还是不敢写,让我知道自己几何有多弱了,伤心了一天,没刷bzoj 1021: [SHOI20 ...
- bzoj千题计划111:bzoj1021: [SHOI2008]Debt 循环的债务
http://www.lydsy.com/JudgeOnline/problem.php?id=1021 如果A收到了B的1张10元,那么A绝对不会把这张10元再给C 因为这样不如B直接给C优 由此可 ...
- BZOJ 1021 [SHOI2008]Debt 循环的债务
1021: [SHOI2008]Debt 循环的债务 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 694 Solved: 356[Submit][S ...
- BZOJ 1021: [SHOI2008]Debt 循环的债务( dp )
dp(i, j, k)表示考虑了前i种钱币(从小到大), Alice的钱数为j, Bob的钱数为k, 最小次数. 脑补一下可以发现, 只有A->B.C, B->A.C, C->A.B ...
- 1021: [SHOI2008]Debt 循环的债务 - BZOJ
Description Alice.Bob和Cynthia总是为他们之间混乱的债务而烦恼,终于有一天,他们决定坐下来一起解决这个问题.不过,鉴别钞票的真伪是一件很麻烦的事情,于是他们决定要在清还债务的 ...
- 【BZOJ 1021】[SHOI2008]Debt 循环的债务
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1021 [题意] [题解] 设f[i][j][k]表示前i种面值的钱币; 第一个人当前的 ...
- BZOJ_1021_[SHOI2008]_Debt循环的债务_(DP)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1021 三个人相互欠钱,给出他们每个人各种面额的钞票各有多少张,求最少需要传递多少张钞票才能把账 ...
- [SHOI 2008]Debt 循环的债务
Description 题库链接 A 欠 B \(x_1\) 元, B 欠 C \(x_2\) 元, C 欠 A \(x_3\) 元.现每人手上各有若干张 100,50,20,10,5,1 钞票.问至 ...
- $bzoj1021-SHOI2008\ Debt$ 循环的债务 $dp$
题面描述 \(Alice\).\(Bob\)和\(Cynthia\)总是为他们之间混乱的债务而烦恼,终于有一天,他们决定坐下来一起解决这个问题.不过,鉴别钞票的真伪是一件很麻烦的事情,于是他们决定要在 ...
随机推荐
- lintcode 443.岛屿的个数
在v2ex上看到有人提到了这个,感觉挺简单的,没忍住还是试一下.... 基本的染色法. AC代码: public class Solution { /** * @param grid a boolea ...
- Mysql储存过程5: while
循环结构 while create procedure name() begin while 条件 do SQL语句 end while; end$ create procedure aa6() be ...
- Ubuntu 14.04 64位上安装wps office软件(转http://m.blog.csdn.net/blog/yhc13429826359/24179933)
废话少说,只给出方法供各位参考!wps for Linux版本已经有两三年没有大的动作,当然其他平台,比如windows,Android,ios上的wps效果还是很赞的说. 下面是我成功安装的步骤: ...
- powerpc平台移植zebra或quagga-0.99.23
1,先configure ./configure --enable-vtysh --disable-bgpd --disable-ripd --disable-ripngd --disable- ...
- cpu几种架构区别
转自:http://smilejay.com/2012/07/intel-procssor-architecture/ (1)x86 (IA-32,i386,x86-32,x32) x86是指基于In ...
- iTextSharp操作pdf之pdfCreater
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- KVC, KVO 实现原理
Key-Value Coding: 键值编码 (KVC) 方法调用: // 对象属性 // 类似: Person -> name setValue: forKey: // 对象的属性或者 属性的 ...
- ButterKnifeZelezny简单使用教程
https://github.com/avast/android-butterknife-zelezny 一,配置butterknife Configure your project-leve ...
- sqlserver如何添加全文索引
在SQL Server 中提供了一种名为全文索引的技术,可以大大提高从长字符串里搜索数 据的速度,不用在用LIKE这样低效率的模糊查询了. 下面简明的介绍如何使用Sql2008 全文索引 一.检查 ...
- Hadoop HDFS 单节点部署方案
初学者,再次记录一下. 确保Java 和 Hadoop已安装完毕(每个人的不一定一样,但肯定都有数据,仅供参考) [root@jans hadoop-2.9.0]# pwd /usr/local/ha ...