0
点赞
收藏
分享

微信扫一扫

2021 Shandong Provincial Collegiate Programming Contest 补题

先峰老师 2022-04-13 阅读 43
c++算法dp

G. Grade Point Average

思路:
k最多1e5位
手工除法模拟

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10; 
const int mod =1e9+7;
int main(){
	int n,k;
	scanf("%d%d",&n,&k);
	int sum=0;
	for(int i=1;i<=n;i++){
		int x;
		scanf("%d",&x);
		sum+=x;
	}
	printf("%d.",sum/n);
	sum%=n;
	while(k--){
		sum*=10;
		printf("%d",sum/n);
		sum%=n;
	}
	return 0;
}  

Dyson Box

思路:
每个箱子如果不与其他箱子相邻,那么贡献是4,
现考虑竖直方向的重力:
如果当前列之前不存在箱子,那么现在加入的这个箱子的贡献值为4;
如果当前列已经存在其他箱子,那么现在加入的这个箱子贡献值减2(在4的基础上);
与此同时,若前一列的箱子数量大于当前列(向下推箱子到底,当前箱子就会与前一列的某个箱子相邻),那么现在加入的这个箱子贡献值再减2;
若后一列的箱子数量也大于当前列,那么现在加入的这个箱子贡献值再减2。

水平方向的重力同理。

注意开longlong

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <string>
#include <algorithm>
#include <queue>
#include <utility>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10; 
const int mod =1e9+7;
int xx[maxn],yy[maxn];
int main(){
	int n;
	cin>>n;
	ll ans1=0;
	ll ans2=0;
	for(int i=0;i<n;i++){
		int x,y;
		cin>>x>>y;
		ans1+=4,ans2+=4;
		if(xx[x]) ans1-=2;
		if(x>=1&&xx[x-1]>xx[x]) ans1-=2;
		if(xx[x+1]>xx[x]) ans1-=2;
		if(yy[y]) ans2-=2;
		if(y>=1&&yy[y-1]>yy[y]) ans2-=2;
		if(yy[y+1]>yy[y]) ans2-=2;
		xx[x]++;
		yy[y]++;
		cout<<ans1<<" "<<ans2<<endl;
	}
	return 0;
}  

H. Adventurer’s Guild

思路:
二维背包
d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]:前 i i i个怪物,当前血量为 j j j,消耗 k k k耐力时能够获得的最大价值。
动态转移方程:
d p [ i ] [ j ] [ k ] = m a x ( d p [ i ] [ j ] [ k ] , d p [ i − 1 ] [ j − h [ i ] − m a x ( 0 , s [ i ] − k ) ] [ m a x ( 0 , k − s [ i ] ) ] + w [ i ] dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-h[i]-max(0,s[i]-k)][max(0,k-s[i])]+w[i] dp[i][j][k]=max(dp[i][j][k],dp[i1][jh[i]max(0,s[i]k)][max(0,ks[i])]+w[i]
利用滚动数组降维

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <string>
#include <algorithm>
#include <queue>
#include <utility>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e3+10; 
const int mod =1e9+7;
int h[maxn],s[maxn],w[maxn];
ll dp[maxn][maxn];
int main(){
	int n,H,S;
	scanf("%d%d%d",&n,&H,&S);
	for(int i=1;i<=n;i++){
		scanf("%d%d%d",&h[i],&s[i],&w[i]);
	}
	for(int i=1;i<=n;i++){
		for(int j=H;j>=1;j--){
			for(int k=S;k>=0;k--){
				if(j>h[i]&&j+k>s[i]+h[i]){
					dp[j][k]=max(dp[j][k],dp[j-h[i]-max(0,s[i]-k)][max(0,k-s[i])]+w[i]);
				}
			}
		}
	}
	printf("%lld\n",dp[H][S]);
	return 0;
}  

Matrix Problem

思路:
思维+构造

Cat Virus

思路:
对于每个父亲结点,都有两种涂色方法,

举报

相关推荐

0 条评论