芝士评测记录:记录
芝士代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=11451,maxm=1140,INF=2147483645;
int n,m,k,st,ans=INF,cnt;
int up[maxn],down[maxn];
int f[maxn][maxm];
bool fl;
int red() {
int as = 0; int fl = 1; char ch = getchar();
while(!isdigit(ch)) {if(ch == '-') fl = -1; ch = getchar();}
while(isdigit(ch)) {as = as * 10 + ch - '0'; ch = getchar();}
return as * fl;
}
struct edge{
int p,h,l;
}e[maxn];
bool cmp(edge a,edge b){
return a.p<b.p;
}
void init(){
n=red();m=red();k=red();
for(int i=0;i<=n-1;i++){ //上一位的up||down
up[i]=red();
down[i]=red();
}
for(int i=1;i<=k;i++){
e[i].p=red();
e[i].l=red();
e[i].h=red();
}
sort(e+1,e+k+1,cmp); //管子按顺序排好
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
f[i][j]=INF; //初始INF最大
st=1; //1号管子预备
}
void dp(){
for(int i=1;i<=n;i++){
if(i==e[st].p&&k!=0){ //过管子的话
fl=false; //判断过了吗用的
for(int h=e[st].l+1;h<=e[st].h-1;h++){
if(h>up[i-1]){
f[i][h]=min(f[i-1][h-up[i-1]]+1,f[i][h]); //上升
if(h+up[i-1]<e[st].h-1){ //连跳
f[i][h+up[i-1]]=min(f[i][h]+1,f[i][h+up[i-1]]);
}
if(h+up[i-1]>m) f[i][m]=min(f[i][h]+1,f[i][m]); //碰天花板的情况
}
if(h<=m-down[i-1]){
f[i][h]=min(f[i-1][h+down[i-1]],f[i][h]); //下降
}
if(f[i][h]!=INF&&f[i][h]>=0){ //但凡改了一个值都算过管子了
fl=true;
}
}
if(fl==false){ //没过就结束了
break;
}
else cnt++; //计数
st++; //下一个管子预备
}
else{
for(int h=1;h<=m;h++){
if(h>up[i-1]){
f[i][h]=min(f[i-1][h-up[i-1]]+1,f[i][h]); //上升
f[i][h+up[i-1]]=min(f[i][h]+1,f[i][h+up[i-1]]); //连跳
if(h+up[i-1]>m) f[i][m]=min(f[i][h]+1,f[i][m]); //碰天花板
}
if(h<=m-down[i-1]){
f[i][h]=min(f[i-1][h+down[i-1]],f[i][h]); //下降
}
for(int k=0;k<=up[i-1];k++){
f[i][m]=min(f[i][m],f[i-1][m-k]+1); //天花板
}
}
}
}
}
void out(){
for(int i=1;i<=m;i++)
ans=min(f[n][i],ans);
if(fl==false&&k!=0){
printf("0\n");
printf("%d\n",cnt);
}
else{
printf("1\n");
printf("%d\n",ans);
}
}
int main() {
init();
dp();
out();
return 0;
}
有没有大佬,求求了。。。