【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1021

【题意】

【题解】



设f[i][j][k]表示前i种面值的钱币;

第一个人当前的钱数为j,第二个人当前的钱数为k;

所需要的最小交换钱币次数;

这里第三个人的钱数就是sum-j-k;

然后我们以钱币的种类划分成6个阶段进行这样的DP;

(这里我们可以一开始通过a,b,c处理出最后第一个人该有多少钱、第二个人该有多少钱…)

DP的依据就是;

同一种类的钱币;

只要确定了某个人要增加或者减少多少个这种类型的钱币个数;

那么最佳的方案就确定了;

即不会出现从A转到B再转到C的情况。

对于这种,A可以直接转到C..

那么也就是说

这种类型的钱如果第一个人的改变量为da,第二个人的改变量为db;

那么最小的交换次数就能确定;

即(abs(da)+abs(db)+abd(da+db))/2

这是最佳的方案;

(同一种钱币)

根据这个规则

枚举第一个人的钱数、第二个人的钱数、这种钱币第一个人最后有多少张,第二个人有多少张.

进行一个类似背包的DP就好.



【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%lld",&x)
#define ref(x) scanf("%lf",&x) typedef pair<int, int> pii;
typedef pair<LL, LL> pll; const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };
const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };
const int val[7] = { 0,1,5,10,20,50,100 };
const double pi = acos(-1.0);
const int N = 1e3+100;
const int INF = 0x3f3f3f3f; int total[4], cnt[4][7],tot[7],sum;
int f[2][N][N],a,b,c,target[3],pre,now; #define UPD(x,y) (x = min(x,y)) int main()
{
//freopen("F:\\rush.txt", "r", stdin);
rei(a), rei(b), rei(c);
rep1(i, 1, 3)
rep2(j, 6, 1)
{
rei(cnt[i][j]);
total[i] += val[j] * cnt[i][j];
tot[j] += cnt[i][j];
sum += val[j] * cnt[i][j];
}
target[1] = total[1] - a + c;
target[2] = total[2] - b + a;
if (target[1] < 0 || target[2] < 0 || sum - target[1] - target[2] < 0)
{
puts("impossible");
return 0;
} pre = now = 0;
memset(f[pre], INF, sizeof f[pre]);
f[pre][total[1]][total[2]] = 0;
rep1(i, 1, 6)
{
pre = now;
now = now ^ 1;
memset(f[now], INF, sizeof f[now]);
rep1(j, 0, sum)
{
int t = sum - j;
rep1(k, 0, t)
{
if (f[pre][j][k] == INF) continue;
UPD(f[now][j][k], f[pre][j][k]);
//assert f[pre][j][k]!=INF
rep1(q, 0, tot[i])
{
int r = tot[i] - q;
rep1(w, 0, r)
{
int da = q - cnt[1][i], db = w - cnt[2][i];
int cnta = j + da*val[i], cntb = k + db*val[i];
if (cnta < 0 || cntb < 0 || sum - cnta - cntb < 0) continue;
UPD(f[now][cnta][cntb], f[pre][j][k] + (abs(da) + abs(db) + abs(da + db)) / 2);
}
}
}
}
}
if (f[now][target[1]][target[2]] == INF) return puts("impossible"), 0;
printf("%d\n", f[now][target[1]][target[2]]);
//printf("\n%.2lf sec \n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}

【BZOJ 1021】[SHOI2008]Debt 循环的债务的更多相关文章

  1. BZOJ 1021 [SHOI2008]Debt 循环的债务

    1021: [SHOI2008]Debt 循环的债务 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 694  Solved: 356[Submit][S ...

  2. BZOJ 1021: [SHOI2008]Debt 循环的债务( dp )

    dp(i, j, k)表示考虑了前i种钱币(从小到大), Alice的钱数为j, Bob的钱数为k, 最小次数. 脑补一下可以发现, 只有A->B.C, B->A.C, C->A.B ...

  3. 1021: [SHOI2008]Debt 循环的债务 - BZOJ

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

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

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

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

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

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

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

  7. BZOJ_1021_[SHOI2008]_Debt循环的债务_(DP)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1021 三个人相互欠钱,给出他们每个人各种面额的钞票各有多少张,求最少需要传递多少张钞票才能把账 ...

  8. BZOJ.1021.[SHOI2008]循环的债务(DP)

    题目链接 不同面额的钞票是可以分开考虑的. ↑其实并不很明白具体(证明?),反正是可以像背包一样去做. f[x][i][j]表示用前x种面额钞票满足 A有i元 B有j元 (C有sum-i-j)所需交换 ...

  9. [SHOI 2008]Debt 循环的债务

    Description 题库链接 A 欠 B \(x_1\) 元, B 欠 C \(x_2\) 元, C 欠 A \(x_3\) 元.现每人手上各有若干张 100,50,20,10,5,1 钞票.问至 ...

随机推荐

  1. 洛谷 P1644 跳马问题

    P1644 跳马问题 题目背景 在爱与愁的故事第一弹第三章出来前先练练四道基本的回溯/搜索题吧…… 题目描述 中国象棋半张棋盘如图1所示.马自左下角(0,0)向右上角(m,n)跳.规定只能往右跳,不准 ...

  2. win8.1 “服务器运行失败”的解决方法

    平台:win8.1 SP1 问题:安装QQ安全管家又卸载后出现了奇怪的问题,1.在桌面点右键→个性化时,提示“服务器运行失败”.2.右键点击“这台电脑”,选择“属性”时没有反应.3.开始屏幕里随便选择 ...

  3. dinic算法学习(以poj1273为例)

    Dinic 算法模板  Dinic算法是一种比較easy实现的.相对照较快的最大流算法. 求最大流的本质,就是不停的寻找增广路径.直到找不到增广路径为止. 对于这个一般性的过程,Dinic算法的优化例 ...

  4. Let's do our own full blown HTTP server with Netty--转载

    原文地址:http://adolgarev.blogspot.com/2013/12/lets-do-our-own-full-blown-http-server.html Sometimes ser ...

  5. GDB如何调试没有符号表(未加-g选项的编译)的程序

    /********************************************************************* * Author  : Samson * Date    ...

  6. openCV 和GDI画线效率对比

    一. 由于项目需要,原来用GDI做的画线的功能,新的项目中考虑到垮平台的问题,打算用openCV来实现,故此做个效率对比. 二. 2点做一条线,来测试效率. 用了同样的画板大小---256*256的大 ...

  7. [Angular2 Form] Nested formGroup, and usage of formGroupName

    We can nest formGorup: this.reactiveForm = fb.group({ username: [ '', [ Validators.required, Validat ...

  8. 使用RxPermissions(基于RxJava2)

    使用RxPermissions(基于RxJava2) 0. 背景 Android 6.0 (API level 23)中.将权限分成了两类.一类是Install权限(称之为安装时权限).还有一类是Ru ...

  9. Classification and Representation

    Classification To attempt classification, one method is to use linear regression and map all predict ...

  10. gerrit docker

    修改项目配置文件 git clone ssh://admin@localhost:29418/All-Projects && scp -p -P 29418 admin@localho ...