zoukankan      html  css  js  c++  java
  • [CSP校内集训]hotel

    题意

    有n个房间分别有(a_i)个人((a_ileq 7)),通过移动人的操作使得一个房间只能有(0,4,7)个人中的一种,花费1单位代价将一个人移动一格,无解输出-1

    样例输入
    7
    1 0 7 0 0 0 3

    样例输出
    6

    思路

    DP直接搞,开始想的是用(dp_{i,j})记录前(i)个房间都合法时多出来了(j)个人,但这样做(j)可能会越来越大

    于是用(dp_{i,j})表示从第(i)个房间向(i+1)移动了(j)个人后,使得第(i)个房间符合条件的最小代价

    第i个房间进来的人可以通过上一层得到,枚举上一层和这一层转移即可,由于可能出现负数(即(i+1)(i)移动),下标需要加上一个数(这里加的是7)

    Code

    #include<bits/stdc++.h>
    #define N 100005
    #define Min(x,y) ((x)<(y)?(x):(y))
    using namespace std;
    typedef long long ll;
    const ll inf = 10000000000000000;
    int n,a[N];
    ll f[N][15];
    
    template <class T>
    void read(T &x)
    {
    	char c;int sign=1;
    	while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48;
    	while((c=getchar())>='0'&&c<='9') x=x*10+c-48; x*=sign;
    }
    
    int main()
    {
    	freopen("hotel.in","r",stdin);
    	freopen("hotel.out","w",stdout);
    	read(n);
    	for(int i=1;i<=n;++i) read(a[i]);
    	for(int i=0;i<=n;++i)
    	  for(int j=0;j<=14;++j)
    	    f[i][j]=inf;
    	
    	f[0][7]=0;
    	for(int i=1;i<=n;++i)
    	  for(int j=0;j<=14;++j)//now
    		for(int k=0;k<=14;++k)//las
    		{
    			int in=k-7,out=j-7;
    			int res=a[i]+in-out;
    			if(res==0||res==4||res==7)  
    			  f[i][j]=Min(f[i][j],f[i-1][k]+abs(in));
    		}
    	cout<<(f[n][7]==inf ? -1 : f[n][7])<<endl;
    	return 0;
    }
    

    讲道理这不是一道氵DP吗,考场上在想什么鬼

  • 相关阅读:
    python脚本2_输入2个数比较大小后从小到大升序打印
    python脚本1_给一个半径求圆的面积和周长
    配置双机互信
    如何在 CentOS7 中安装 Nodejs
    Git 服务器搭建
    docker安装脚本
    CentOS7下安装Docker-Compose
    Linux 文件锁
    6 系统数据文件和信息
    bash脚本编程之二 字符串测试及for循环
  • 原文地址:https://www.cnblogs.com/Chtholly/p/11639483.html
Copyright © 2011-2022 走看看