蒟蒻,菜菜,大佬,捞捞,呜呜。。。
  • 板块P1220 关路灯
  • 楼主Dr_MING
  • 当前回复4
  • 已保存回复4
  • 发布时间2022/11/1 20:29
  • 上次更新2023/10/27 04:34:49
查看原帖
蒟蒻,菜菜,大佬,捞捞,呜呜。。。
579266
Dr_MING楼主2022/11/1 20:29

芝士代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=51,INF=2147483640;
int n,c,pos[maxn],v[maxn];
int f[maxn][maxn],t[maxn][maxn];//f代表消耗功率,t代表到此的时间 
bool vis[maxn][maxn];			//0向左走(或者说指针在此区间左侧),1向右走 
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;	
}

void init(){
	n=red();c=red();
	for(int i=1;i<=n;i++){
		pos[i]=red();
		v[i]=red();
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			f[i][j]=INF;
		}
	}
	f[c][c]=0;
}

void dp(){
	for(int k=2;k<=n;k++){
		for(int i=c-k+1,j=i+k-1;i<=c;i++,j++){
			if(i<=0||j>=n+1)		continue;			//跳过不适合的区间 
			if(j!=c+k-1){								//不在最右边(同下) 
				if(vis[i+1][j]==0){
					if(f[i+1][j]+(pos[i+1]-pos[i]+t[i+1][j])*v[i]<f[i][j]){
						f[i][j]=f[i+1][j]+(pos[i+1]-pos[i]+t[i+1][j])*v[i];
						t[i][j]=pos[i+1]-pos[i]+t[i+1][j];
						vis[i][j]=0;
					}
				}
				if(vis[i+1][j]==1){
					if(f[i+1][j]+(pos[j]-pos[i]+t[i+1][j])*v[i]<f[i][j]){
						f[i][j]=f[i+1][j]+(pos[j]-pos[i]+t[i+1][j])*v[i];
						t[i][j]=pos[j]-pos[i]+t[i+1][j];
						vis[i][j]=0;
					}
				}
			}	
			if(i!=c-k+1){								//不在最左边(但反错加个左边的数就溢出变负了)			
				if(vis[i][j-1]==0){
					if(f[i][j-1]+(pos[j]-pos[i]+t[i][j-1])*v[j]<f[i][j]){
						f[i][j]=f[i][j-1]+(pos[j]-pos[i]+t[i][j-1])*v[j];
						t[i][j]=pos[j]-pos[i]+t[i][j-1];
						vis[i][j]=1;
					}
				}
				if(vis[i][j-1]==1){
					if(f[i][j-1]+(pos[j]-pos[j-1]+t[i][j-1])*v[j]<f[i][j]){
						f[i][j]=f[i][j-1]+(pos[j]-pos[j-1]+t[i][j-1])*v[j];
						t[i][j]=pos[j]-pos[j-1]+t[i][j-1];
						vis[i][j]=1;
					}
				}
			}
//	调试	cout<<i<<" "<<j<<endl;
//	用的	cout<<f[i][j]<<" "<<t[i][j]<<" "<<vis[i][j]<<endl;
		}
	}
}

int main(){
	init();
	dp();
	printf("%d",f[1][n]);		//输出区间1-n的就行了 
	return 0;
}
//31980
2022/11/1 20:29
加载中...