题解P4026 [SHOI2008]循环的债务

一道比较难想的DP

可以想到,每个面额的钞票之间是可以独立计算的

那么就可以对于每一种面额的钞票单独考虑,接下来就是状态的定义了

有一种比较好想的状态就是定义 \(f_{i,x,y,z}\) 表示前 \(i\) 种钞票, 每个人分别有多少钱,但很明显会超空间.

仔细观察可以发现,钞票的总面额是不变的,那么状态就可以优化掉一维,只需要表示出两个人所有的面额就可以计算出第三个人

然后状态的转移就比较简单了,直接枚举钞票的数量就行了

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#define INF 0x3f3f3f3f
using namespace std;

int f[7][1005][1005];
int x1, x2, x3, sum;
int n[4][7], s[4], cnt[7];
int val[7] = {0, 100, 50, 20, 10, 5, 1};

int main()
{
    scanf("%d%d%d", &x1, &x2, &x3);
    for (int i = 1; i <= 3; i++)
        for (int j = 1; j <= 6; j++)           
        {
            scanf("%d", &n[i][j]);
            sum += n[i][j] * val[j], s[i] += n[i][j] * val[j];
            cnt[j] += n[i][j];
        }
    memset(f, 0x3f, sizeof(f));
    f[0][s[1]][s[2]] = 0;  
    for (int i = 1; i <= 6; i++)
    {
        for (int j = 0; j <= sum; j++)
        {
            for (int k = 0; k + j <= sum; k++)
            {
                if (f[i - 1][j][k] == INF)
                    continue;
                f[i][j][k] = f[i - 1][j][k];
                for (int t1 = 0; t1 <= cnt[i]; t1++)
                {
                    for (int t2 = 0; t2 + t1 <= cnt[i]; t2++)
                    {
                        int now1 = j - (n[1][i] - t1) * val[i];
                        int now2 = k - (n[2][i] - t2) * val[i];
                        int t3 = cnt[i] - t1 - t2;
                        if (now1 >= 0 && now2 >= 0 && sum >= now1 + now2)
                        {
                            int t = abs(n[1][i] - t1) + abs(n[2][i] - t2) + abs(n[3][i] - t3);
                            f[i][now1][now2] = min(f[i][now1][now2], f[i - 1][j][k] + t / 2);//除以2是因为是交换
                        }
                    }
                }
            }
        }
    }
    int ans = INF, s1 = s[1] - x1 + x3, s2 = s[2] - x2 + x1;
    for (int i = 0; i <= 6; i++)
        ans = min(ans, f[i][s1][s2]);
    if (s1 < 0 || s2 < 0 || sum < s1 + s2 || ans == INF)
        printf("impossible");
    else
        printf("%d", ans);
    return 0;
}
posted @ 2021-04-12 09:47  DSHUAIB  阅读(48)  评论(0编辑  收藏  举报