2021第十二届山东省赛 D(模拟) H(01背包) G(模拟)

Posted 行码棋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021第十二届山东省赛 D(模拟) H(01背包) G(模拟)相关的知识,希望对你有一定的参考价值。

D(模拟)

题意:
每次有一个方块放在二维平面上,将重力方向分别改为向下和向左,输出每次的图形的边长

思路:
统计每个坐标轴上的方块的数目,先把边长加上4,如果方块数目大于等于2,就减去2,因为两个方块间重合了,少了两个长度的边长。如果左右两边的方块数目大于等于该方向上的方块数目,左右的边长也会重合,也要减去2

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+5;
int cnt[2][N];
int n;
int main()
{
    int ans1 = 0,ans2=0;
    cin>>n;
    while(n--)
    {
        int x,y;
        cin>>x>>y;
        cnt[0][x]++,cnt[1][y]++;
        ans1 += 4,ans2 += 4;
        if(cnt[0][x]>=2) ans1 -= 2;
        if(cnt[1][y]>=2) ans2 -= 2;
        if(cnt[0][x-1]>=cnt[0][x]) ans1 -= 2;
        if(cnt[1][y-1]>=cnt[1][y]) ans2 -= 2;
        if(cnt[0][x+1]>=cnt[0][x]) ans1 -= 2;
        if(cnt[1][y+1]>=cnt[1][y]) ans2 -= 2;
        cout<<ans1<<" "<<ans2<<'\\n';
    }
    
    return 0;
}

H(01背包)

在这里插入图片描述

题意:
大概意思就是说一个人有H的生命值,S的体力值,他需要打怪获得奖励金币,打一个怪会损失掉 h i h_i hi的生命值和 s i s_i si的体力值,当生命值小于等于0时,他就会死掉,但是如果体力值小于零,他的生命值就会减掉相应体力负值的绝对值,问在不死的情况下,获得最大的金币值。

思路:
经典的01背包问题,其实就是容量变成二维的了,其它的不变,需要从后往前遍历容量,因为是二维滚动数组。

状态表示:
d p [ i ] [ j ] dp[i][j] dp[i][j] i i i的生命值和 j j j的体力值能够获得的最大金币数

转移方程:
体力值不为负时:
d p [ j ] [ k ] = m a x ( d p [ j ] [ k ] , d p [ j − h [ i ] ] [ k − s [ i ] ] + w [ i ] ) dp[j][k] = max(dp[j][k],dp[j-h[i]][k-s[i]]+w[i]) dp[j][k]=max(dp[j][k],dp[jh[i]][ks[i]]+w[i])
体力为负时:
生命值最终为 ( j − h [ i ] ) + ( k − s [ i ] ) (j-h[i])+(k-s[i]) (jh[i])+(ks[i])
d p [ j ] [ k ] = m a x ( d p [ j ] [ k ] , d p [ j + k − s [ i ] − h [ i ] ] [ 0 ] + w [ i ] ) dp[j][k] = max(dp[j][k],dp[j+k-s[i]-h[i]][0]+w[i]) dp[j][k]=max(dp[j][k],dp[j+ks[i]h[i]][0]+w[i])


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e3+5;
ll dp[305][305];
ll s[N],h[N],w[N];

int main()
{
    int n,S,H;
    cin>>n>>S>>H;
    for(int i=1;i<=n;i++) cin>>s[i]>>h[i]>>w[i];
    for(int i=1;i<=n;i++)
    {
        for(int j=300;j>=0;j--)
        {
            for(int k=300;k>=0;k--)
            {
                if(j-s[i]>0 && k>=h[i])
                    dp[j][k] = max(dp[j][k],dp[j-s[i]][k-h[i]]+w[i]);
                else if(j>s[i] && j+k-h[i]-s[i]>0)
                    dp[j][k] = max(dp[j][k],dp[j+k-h[i]-s[i]][0]+w[i]);
            }
        }
    }
    
    cout<<dp[S][H]<<'\\n';
    return 0;
}

G

题意:
具体就是对一个假分数算出后k为小数,进行输出。

思路:
先输出整数位,再输出小数位
每个小数位就是乘10,模n的操作

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,k;

int main()
{
    ll sum = 0;
    cin>>n>>k;
    for(int i=1;i<=n;i++) 
    {
        int num;cin>>num;
        sum+=num;
    }
    cout<<sum/n<<".";
    int t = sum%n;
    for(int i=1;i<=k;i++)
    {
        t*=10;
        cout<<t/n;
        t%=n;
    }
    return 0;
}

以上是关于2021第十二届山东省赛 D(模拟) H(01背包) G(模拟)的主要内容,如果未能解决你的问题,请参考以下文章

第十二届蓝桥杯 2021年国赛真题 (Java 大学B组)

第十二届蓝桥杯 2021年省赛真题 (Java 大学B组) 第一场 (更新中)

2021.5.9 第十二届蓝桥杯大赛软件赛省赛第二场大学B组(个人题解)

2021软件类第十二届蓝桥杯国赛真题 Python组 A-E题解

第十二届蓝桥杯大赛软件赛省赛第二场C++B组

2021 第十二届蓝桥杯大赛软件赛省赛(第二场),C/C++大学B组题解