因为成为英雄的旅程,往往伴随着|

伊埃斯

园龄:2个月粉丝:4关注:7

2025-02-09日记

你硕德对,蛋柿现在是日记时间。

洛谷讨论区昨天爆炸了,究其原因是洛谷国际站有人发 nc 内容,直接被罚了 100 万。重要的是:

他的注册资本都才 200 万。

然后今天早上来了一个 综合训练。其实就是 IOI 赛制的模拟赛,只不过有 6 题,从做题的顺序来说吧。

Count The Bits

这道题是场切的,就是一道简单的不能再简单的数位 dp。还是说一下。

先想状态。设 dppos,cnt,p 表示填到了第 pos 位,总共有 cnt1,这个数 modk=p 时的方案数。我们直接开始记搜。搜索边界就是当 pos=b 时,如果 p=0return cnt 否则 return 0

放一下简单至极的代码:

#include<bits/extc++.h>
#pragma GCC optimize(2)
#pragma GCC target("avx")
using namespace std;
typedef long long ll;
const ll mod = 1000000009;
int k,b;
ll dp[130][130][1005];
ll dfs(int pos,int cnt,int p)
{
    if (~dp[pos][cnt][p])
        return dp[pos][cnt][p];
    if (pos == b)
        return p == 0 ? cnt : 0;
    ll ret = 0;
    for (int i = 0; i < 2; i++)
        ret = (ret + dfs(pos + 1,cnt + i,(p << 1 | i) % k)) % mod;
    return dp[pos][cnt][p] = ret;
}
signed main()
{
    scanf("%d%d",&k,&b);
    memset(dp,0xff,sizeof dp);
    printf("%lld",dfs(0,0,0));
    return 0;
}

之前考试有一道这样的题,但是那道题的 k 很大,大到 dp 数组存不下的地步,但是我们发现,k 越大暴力越快。当 dp 存不下时,我们就可以直接上暴力了。

Space Station

这道题也是一道搜索题。直接上记搜。但是我上午实在是太颓废了导致根本没有想这道题。

其实很简单。我们看 ai50,想到用桶。(其实我赛时想到的是 ai5×106,就存得下 dp 数组,然后就这么的错了)cnti 表示 i 的出现次数。对 cnt 算哈希用来记忆化。然后就这么做完了。

放下代码:

#include<bits/extc++.h>
#define int long long
using namespace std;
typedef unsigned long long ull;
const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;
const int base = 97;
int n;
int cnt[55],cnt0,_max;
int a[maxn];
int fac[maxn];
__gnu_pbds::gp_hash_table<ull,int>dp;
void init(int up = 1e5)
{
    fac[0] = 1;
    for (int i = 1; i <= up; i++)
        fac[i] = fac[i - 1] * i % mod;
}
inline ull hsh()
{
    ull ret = 0;
    for (int i = 50; i >= 0; i--)
        ret = ret * base + cnt[i];
    return ret;
}
int dfs(int sum,int stp)
{//sum表示现在数字的和,stp表示还剩多少步
    if (!stp)//走完了就直接return   
        return 1;
    if (sum >= _max)//如果现在的和已经大于最大的数了,那么剩下的随便走,有stp的阶乘种情况。
        return fac[stp];
    ull hs = hsh();//哈希
    int ret = 0;
    if (dp.find(hs) != dp.end())//如果搜过了
        return dp[hs];
    for (int i = 1; i <= sum; i++)
    {
        if (cnt[i])
        {
            cnt[i]--;
            ret = (ret + (cnt[i] + 1) * dfs(min(_max,sum + i),stp - 1) % mod) % mod;
            cnt[i]++;
        }
    }
    return dp[hs] = ret;//记忆化
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    init();
    cin >> n >> a[0];
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        cnt[a[i]]++;
        cnt0 += (a[i] == 0);
        _max = max(_max,a[i]);
    }
    int ans = dfs(a[0],n - cnt0);
    for (int i = n; i > n - cnt0; i--)
        ans = ans * i % mod;
    cout << ans;
    return 0;
}

Sum of Numbers

我们先感性理解,每一段肯定是长度差不多的。设 len=nk+1,那么每一段的长度肯定不会超过 len,我们就可以按照这个来 dp 了。

code:

#include<bits/extc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC target("avx")
#define int long long
using namespace std;
const int maxn = 2e5 + 5;//数组开小调了一下午
int n,k,len;
bool vis[maxn];
string s;
struct long_int//这个高精度真的写死人了
{
    static const int base = 1e18;
    static const int wid = 18;
    vector<int>val;
    long_int(int len = 0){val.resize(len,0);}
    long_int(const string &s)
    {
        int it = s.size();
        while ((it - wid) >= 0)
            val.push_back(stoll(s.substr(it -= wid,wid)));
        if (it > 0)
            val.push_back(stoll(s.substr(0,it)));
    }
    friend ostream &operator<<(ostream &out,const long_int &x)
    {
        if (x.val.empty())
            return out << '0';
        out << x.val.back();
        for (int i = x.val.size() - 2; i >= 0; i--)
            out << setw(wid) << setfill('0') << x.val[i];
        return out;
    }
    friend long_int operator+(const long_int &x,const long_int &y)
    {
        long_int ret(max(x.val.size(),y.val.size()));
        int f = 0,len = ret.val.size(),lenx = x.val.size(),leny = y.val.size();
        for (int i = 0; i < len; i++)
        {
            if (i >= lenx)
                ret.val[i] = y.val[i] + f;
            else if (i >= leny)
                ret.val[i] = x.val[i] + f;
            else
                ret.val[i] = x.val[i] + y.val[i] + f;
            if (ret.val[i] >= base)
            {
                f = ret.val[i] / base;
                ret.val[i] %= base;
            }
            else
                f = 0;
        }
        if (f)
            ret.val.push_back(f);
        return ret;
    }
    friend bool operator<(const long_int &x,const long_int &y)
    {
        if (x.val.size() ^ y.val.size())
            return x.val.size() < y.val.size();
        for (int i = x.val.size() - 1; i >= 0; i--)
            if (x.val[i] ^ y.val[i])
                return x.val[i] < y.val[i];
        return 0;
    }
}dp[maxn];
void solve()
{
    cin >> n >> k >> s;
    fill(vis + 1,vis + n + 1,0);
    len = n / (k + 1) + 2;
    for (int x = 0; x <= k; x++)
    {
        for (int i = n; i >= max(1ll,n - len * (k - x)); i--)
        {
            for (int j = max(0ll,i - len); j <= min(x * len,i - 1); j++)
            {
                if (!j || vis[j])
                {
                    long_int tmp = dp[j] + s.substr(j,i - j);
                    if (!vis[i] || tmp < dp[i])
                    {
                        dp[i] = tmp;
                        vis[i] = 1;
                    }
                }
            }
        }
    }
    cout << dp[n] << '\n';
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

然后颓废的一天就这么的结束了。今天晚上好像高三的返校,而我们比他们早一天返校,我们还跟他们一起放假。

比高三的放的还短,这辈子有了

posted @   伊埃斯  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起