zoukankan      html  css  js  c++  java
  • ABC182 F Valid payments

    解法一

    首先不妨来思考一下怎样的一个付钱方案是最优的,假设需要支付 (Y) 元,第 (a_i) 种钱币支付了 (s_i) 张,那么必须有:(s_i < frac{a_{i + 1}}{a_i})

    否则一定可以通过调整减少钱币数量,那么若满足这个条件,付钱方案就是最优的了。

    因为你付的钱和售货员找的钱当中一定存在一个 (s_i = 0),那么我们可以考虑将售货员找的钱取反就能恰好通过一个 (s) 序列表示一种可行的支付方案了。

    于是问题转化为这样一个问题,求 (s) 序列的数量,满足:

    [sum a_i imes s_i = X(-frac{a_{i + 1}}{a_i} < s_i < frac{a_{i + 1}}{a_i}) ]

    同时通过这一条件,还可以推出 (forall i, sumlimits_{j < i} a_j imes s_j < a_i)

    因此,(forall i) 应该要满足:(|sumlimits_{j ge i} a_j imes s_j - X| < a_i),注意到 (a_i mid sumlimits_{j ge i} a_j imes s_j),因此这里的 (sumlimits_{j ge i} a_j imes s_j) 至多只有两种取值。

    那么我们可以先计算出 (forall i, sumlimits_{j ge i} a_j imes s_j) 的取值,然后就可以基于取值很少设计一个 (dp) 了。

    不难发现可以令 (f_{i, j}) 表示 (sumlimits_{k ge i} a_k imes s_k = j) 时的方案数,转移时只需判断前后两个后缀之差这个位置是否能组成即可。

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    #define rep(i, l, r) for (int i = l; i <= r; ++i)
    #define dep(i, l, r) for (int i = r; i >= l; --i)
    const int N = 50 + 5;
    int n, X, ans, a[N], cnt[N], b[N][3], dp[N][3];
    signed main () {
        cin >> n >> X;
        rep(i, 1, n) {
            cin >> a[i];
            int L = ceil(1.0 * (X - a[i] + 1) / a[i]), R = (X + a[i] - 1) / a[i];
            rep(j, L, R) b[i][++cnt[i]] = j * a[i];
        }
        rep(i, 1, cnt[n]) dp[n][i] = 1;
        dep(i, 1, n - 1) 
            rep(j, 1, cnt[i]) 
                rep(k, 1, cnt[i + 1]) 
                    if(abs(b[i + 1][k] - b[i][j]) / a[i] < a[i + 1] / a[i]) 
                        dp[i][j] += dp[i + 1][k];
        rep(i, 1, cnt[1]) ans += dp[1][i];
        cout << ans;
        return 0;
    }
    

    解法二

    同样需要解法一当中付钱方案最优的思考,接下来你会发现这个东西本质上是一个类似进制的东西。

    假设 (Y, Z) 分别为你付的钱,收获员找的钱,那么应该满足 (X + Z = Y)

    将这个东西类似于十进制加法一样在这个类进制下考虑,你会发现 (Z, Y) 中在某一位必须至少有一个为 (0)

    (X) 这位也为 (0) 那么 (Z) 这一位只能填 (0),否则 (Z) 只能填一个使得这一位恰好进位的数。

    那么此时本质上之前位填的数对当前位的影响只有进位或不进位两种,所以可以令 (f_{i, 0 / 1}) 表示考虑到第 (i) 位之前有没有进位的方案数即可。

    关于(类)进制的一条重要性质:(forall i, sumlimits_{j < i} a_j imes s_j < a_i)

    另外这种涉及某种进制在一些位取值不同的情况下的运算时,一定要有类似于十进制数加法运算的思考。

  • 相关阅读:
    开源中国在线插件工具
    本本变身路由 iPad通过笔记本上网(转)
    Windows 7 中让IIS7支持shtml功能及在ASP.Net中使用UrlRewritingNet实现链接重写
    URLRewrite伪静态与AspNetPager分页控件的结合
    CSS 连接地址后面加上问号(?)表示什么意思?
    .net 下如何将文档文件(Word, Pdf等) 中的文本提取出来(转)
    常用JQuery插件整理(转)
    解决PowerDesigner 16 Generate Datebase For Sql2005 找不到sysproperties表的问题(转,并修改了里面的错误)
    Jquery实用代码片段(转)
    Jquery+ashx当把鼠标放到每篇文章时,自动显示该文章的缩略内容( 图片)的异步加载方法
  • 原文地址:https://www.cnblogs.com/Go7338395/p/14028498.html
Copyright © 2011-2022 走看看