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[j−h[i]][k−s[i]]+w[i])
体力为负时:
生命值最终为 ( j − h [ i ] ) + ( k − s [ i ] ) (j-h[i])+(k-s[i]) (j−h[i])+(k−s[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+k−s[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.5.9 第十二届蓝桥杯大赛软件赛省赛第二场大学B组(个人题解)