noip模拟三
垫底了 T1 0,T2 0,T3 5,T4 0
T1 挂了100pts,再也不#define int long long
了
updata:T3 因为没有#define int long long
挂了10分
我是挂分大王!!!!!!!
我挂的分数是我所得分数的 \(\Huge{22}\) 倍!!!!
T1 超市抢购
水题
千万别#define int long long
,因为数据生成器是利用unsigned int自然溢出的
\(code:\)
点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
using ll=long long;using ull=unsigned long long;
const int N = 1e7+10;
int a[N],b[N];
int randseed,n;
unsigned int rnd(){
unsigned int r;
r = randseed = randseed * 1103515245ull + 12345ull;
return (r << 16) | ((r >> 16) & 0xFFFF);
}
signed main(){
#ifndef ONLINE_JUDGE
infile("in.in");outfile("out.out");
#else
#endif
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
cin>>n>>randseed;
int sum=0;
for (int i=n;i>=1;i--)
{
a[i]=rnd()%1000,b[i]=rnd()%1000;
if (sum+(a[i]-b[i])<0) swap(a[i],b[i]);
sum+=(a[i]-b[i]);
}
ll ans = 0;
for(int i = 1;i < n; ++i){
while(b[i] > a[i]) a[i]++,a[i+1]--,ans++;
}
cout<<ans;
}
T2 核酸检测
难题,我不会。
\(f_i\)表示在第\(i\)处喊,所有\(l\le i\)的人都听见了,最少要喊多少句。同时新开一个数组记录方案数
转移方程为\(f_i=\min_{j<i}f_j+1\),\(j\)可以向\(i\)转移时,仅有没有人出来的区间\([L,R]\)满足\(j<L\le R<i\)
记录一个数组\(R\),表示起点时\(i\)的所有人中,终点的最小值是多少。
所以上述转移条件等价于\(\min_{k=j+1}^{i-1}R_k\ge i\)
然后枚举,累加就行了
点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
using ll=long long;using ull=unsigned long long;
const int N = 1e5 + 10,mod = 1e9 + 7;
int n,f[N],way[N],R[N],mx;
pair<int,int> a[N];
signed main(){
#ifndef ONLINE_JUDGE
infile("in.in");outfile("out.out");
#else
#endif
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
cin>>n; memset(R,0x3f,sizeof R);
for(int i = 1,l,r;i <= n; ++i)
cin>>l>>r,R[l] = min(R[l],r),mx = max(mx,r);
way[0] = 1;
for(int i = 1;i <= mx; ++i){
int minn = f[i - 1];
for(int j = i - 1;j >= 1; --j){
if(R[j] >= i) minn = min(minn,f[j-1]);
else break;
}
f[i] = minn + 1;
if(minn == f[i - 1]) way[i] = (way[i - 1] + way[i]) % mod;
for(int j = i - 1;j >= 1; --j){
if(R[j] >= i){
if(f[j - 1] + 1 == f[i])
way[i] = (way[j - 1] + way[i]) % mod;
}
else break;
}
}
int ans = INT_MAX;
for(int i = 1;i <= mx; ++i){
bool flag = true;
for(int j = i + 1;j <= mx; ++j){
if(R[j] <= mx){flag = false;break;}
}
if(flag) ans = min(ans,f[i]);
}
cout<<ans<<'\n';
ll ans1 = 0;
for(int i = 1;i <= mx; ++i){
bool flag = true;
for(int j = i + 1;j <= mx; ++j){
if(R[j] <= mx){flag = false;break;}
}
if(flag && f[i] == ans) ans1 = (ans1 + way[i]) % mod;
}
cout<<ans1;
}
T3 七龙珠
赛时想到正解了,然后,打挂了……
背包跑一遍,用bitset可以优化常数,STL的东西基本全套上去,就完了。
STL大胜利
记得去重和开 long long
点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
using ll=long long;using ull=unsigned long long;
#define int long long
const int N = 1e5 + 10;
int m,k,A,B,C,D,E,F,G;
int a[8][10010];
vector<ll> ok[8];
bitset<N> f;
ll ch[N],len[8];
vector<int> op;
struct node{
int val;
vector<int> op;
inline bool operator < (node y) const {
return val < y.val;
}
};
priority_queue<node> q;
set<vector<int> > pd;//去重
signed main(){
#ifndef ONLINE_JUDGE
infile("in.in");outfile("out.out");
#else
#endif
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
cin>>m>>k;
for(int i = 1;i <= 7; ++i) cin>>ch[i];
for(int i = 1,x;i <= 7; ++i){
cin>>a[i][0];
x = a[i][0];
for(int j = 1;j <= x; ++j)
cin>>a[i][j];
}
for(int now = 1;now <= 7; ++now){
f.reset();
f[0] = true;
int len = a[now][0];
for(int i = 1;i <= len; ++i){
int emm = a[now][i];
f|=(f<<emm);
}
if(ch[now]>0)
for(int i = m;i >= 0; --i)
if(f[i]) ok[now].emplace_back(i);
if(ch[now]<0)
for(int i = 0;i <= m; ++i)
if(f[i]) ok[now].emplace_back(i);
}
for(int i = 1;i <= 7; ++i) op.emplace_back(0);
ll res = 0;
for(int i = 1;i <= 7; ++i) res += ch[i]*ok[i][op[i-1]];
pd.insert(op);
q.push({res,op});
k--;
while(k){
int now = q.top().val;
vector<int> op = q.top().op;
if(!k) return cout<<now,0;
k--;
q.pop();
int res = 0;
for(int i = 1;i <= 7; ++i){
if(op[i-1] == ok[i].size()-1) continue;
vector<int> emm = op;
emm[i-1]++;
if(pd.count(emm)) continue;
int res = 0;
for(int j = 1;j <= 7; ++j) res += ch[j]*ok[j][emm[j-1]];
pd.insert(emm);
q.push({res,emm});
}
}
cout<<q.top().val;
}
T4 龙珠游戏
将题意转化一下,变成小明吃了k颗龙珠后,龙有k个抢吃券。
设\(f_{l,r,k}\)表示要吃掉\([l,r]\),龙有k个抢吃券,轮到小明吃时,小明最多可以吃几颗龙珠
设\(dp_{l,r,k}\)表示要吃掉\([l,r]\),龙有k个抢吃券,轮到龙吃时,小明最少可以吃几颗龙珠
则有转移方程
\[f_{l,r,k}=\max dp_{l,r-1,k+1}+val(r),dp_{l+1,r,k+1}+val(l)
\]
\[dp_{l,r,k}=\min f_{l,r,k},dp_{l+1,r,k-1},dp_{l,r-1,k-1}
\]
点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
using ll=long long;using ull=unsigned long long;
const int N = 502;
int n,f[N][N][N/2],a[N],dp[N][N][N/2];
signed main(){
#ifdef ONLINE_JUDGE
infile("in.in");outfile("out.out");
#else
#endif
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
cin>>n;
for(int i = 1;i <= n; ++i) cin>>a[i];
for(int len = 1;len <= n; ++len){
for(int l = 1;l + len - 1 <= n; ++l){
int r = l + len - 1;
for(int k = 1;k <= n/2; ++k){
f[l][r][k] = max(dp[l][r-1][k+1]+a[r],dp[l+1][r][k+1]+a[l]);
dp[l][r][k] = min({f[l][r][k],dp[l+1][r][k-1],dp[l][r-1][k-1]});
}
f[l][r][0] = dp[l][r][0] = max(dp[l][r-1][1]+a[r],dp[l+1][r][1]+a[l]);
}
}
cout<<f[1][n][0];
}
太唐了
__________________________________________________________________________________________
本文来自博客园,作者:CuFeO4,转载请注明原文链接:https://www.cnblogs.com/hzoi-Cu/p/18296128