2025-02-09日记
你硕德对,蛋柿现在是日记时间。
洛谷讨论区昨天爆炸了,究其原因是洛谷国际站有人发 nc 内容,直接被罚了 万。重要的是:
他的注册资本都才 万。
然后今天早上来了一个 综合训练。其实就是 IOI 赛制的模拟赛,只不过有 题,从做题的顺序来说吧。
Count The Bits
这道题是场切的,就是一道简单的不能再简单的数位 dp。还是说一下。
先想状态。设 表示填到了第 位,总共有 个 ,这个数 时的方案数。我们直接开始记搜。搜索边界就是当 时,如果 就 return 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;
}
之前考试有一道这样的题,但是那道题的 很大,大到 数组存不下的地步,但是我们发现, 越大暴力越快。当 存不下时,我们就可以直接上暴力了。
Space Station
这道题也是一道搜索题。直接上记搜。但是我上午实在是太颓废了导致根本没有想这道题。
其实很简单。我们看 ,想到用桶。(其实我赛时想到的是 ,就存得下 数组,然后就这么的错了) 表示 的出现次数。对 算哈希用来记忆化。然后就这么做完了。
放下代码:
#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
我们先感性理解,每一段肯定是长度差不多的。设 ,那么每一段的长度肯定不会超过 ,我们就可以按照这个来 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;
}
然后颓废的一天就这么的结束了。今天晚上好像高三的返校,而我们比他们早一天返校,我们还跟他们一起放假。
比高三的放的还短,这辈子有了
本文来自博客园,使用 CC BY-NC-SA 4.0 协议。
作者:伊埃斯,转载请注明原文链接:https://www.cnblogs.com/Eous/p/18706680
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!