[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\)总是为他们之间混乱的债务而烦恼,终于有一天,他们决定坐下来一起解决这个问题.不过,鉴别钞票的真伪是一件很麻烦的事情,于是他们决定要在 ...
随机推荐
- Callback2.0
Callback定义? a callback is a piece of executable code that is passed as an argument to other code, wh ...
- pythonif语句和循环语句
1.if语句用法 # if语句用法(缩进相同的成为一个代码块) score=90 if score>=60: print("合格") print("OK" ...
- 用C#实现对MSSqlServer数据库的增删改查---Server层(WaterLevelSetServer.cs、DeviceSetServer.cs)
在Server层定义WaterLevelSetServer和WaterLevelRecordServer两个子类,分别继承DeviceSetServer和DeviceRecordServer. usi ...
- 基于scrapy的分布式爬虫抓取新浪微博个人信息和微博内容存入MySQL
为了学习机器学习深度学习和文本挖掘方面的知识,需要获取一定的数据,新浪微博的大量数据可以作为此次研究历程的对象 一.环境准备 python 2.7 scrapy框架的部署(可以查看上一篇博客的简 ...
- nfs服务器配置
安装 nfs-utils,该软件包提供了 NFS 工具: # yum install nfs-utils 配置启动脚本,使得共享在系统每次启动时都有效: # chkconfig --add rpcbi ...
- python模块之xml.etree.ElementTree
xml.etree.ElementTree用于解析和构建XML文件 <?xml version="1.0"?> <data> <country nam ...
- PIL图片合成旋转缩放
用PIL实现图片的旋转,缩放,合成 我们需要知道合成位置的中心点坐标,用中心点坐标,不使用左顶点的坐标是由于缩放过程容易计算. 假设A是局部透明的图片,我们希望把B放在A的底部,仅从A的透明部分显示B ...
- LeetCode312. Burst Balloons
Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by ...
- **CodeIgniter系列 添加filter和helper
filter: 使用CI的hooks来实现filter. 1.在system/application/config/config.php中,把enable_hooks的值改为TRUE $config[ ...
- zabbix 监控 oracle 数据库
https://blog.csdn.net/dyllove98/article/details/41120853