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];
}

太唐了

posted @ 2024-07-11 18:43  CuFeO4  阅读(7)  评论(0编辑  收藏  举报