洛谷 题解 P1220 【关路灯 】

搜索

  • 传参
inline void DFS(int now,int l,int r,int cnt,int sum,int k)
/*
now为当前点
l为左端点
r为右端点
cnt为当前耗电量
sum为开着的灯的总耗电
k为还有几盏灯开着
*/
  • 开始搜索
if(l>1)DFS(l-1,l-1,r,cnt+(m[now]-m[l-1])*sum,sum-w[l-1],k-1);
//若左端点可以向前移,那么就往前移一个单位,顺便更新一下值
if(r<n)DFS(r+1,l,r+1,cnt+(m[r+1]-m[now])*sum,sum-w[r+1],k-1);
//若右端点可以向后移,那么就往前移一个单位,顺便更新一下值
  • 剪枝
if(cnt>=ans)return;//很好理解
  • 初始参数
DFS(c,c,c,0,tot-w[c],n-1);
//当前所在的路灯肯定被关掉了

完整代码:

#include<bits/stdc++.h>
using namespace std;
int n,c;
int w[60],m[60];
int tot,ans=0x3f3f3f3f;
inline int read()
{
    int tot=0;
    char c=getchar();
    while(c<'0'||c>'9')
        c=getchar();
    while(c>='0'&&c<='9')
    {
        tot=tot*10+c-'0';
        c=getchar();
    }
    return tot;
}
inline void DFS(int now,int l,int r,int cnt,int sum,int k)
{
    if(cnt>=ans)return;
    if(!k)
    {
        ans=cnt;
        return;
    }
    //cout<<now<<" "<<l<<" "<<r<<" "<<cnt<<" "<<sum<<" "<<k<<endl;
    if(l>1)DFS(l-1,l-1,r,cnt+(m[now]-m[l-1])*sum,sum-w[l-1],k-1);
    if(r<n)DFS(r+1,l,r+1,cnt+(m[r+1]-m[now])*sum,sum-w[r+1],k-1);
}
int main()
{
    n=read();c=read();
    for(int i=1;i<=n;i++)
        m[i]=read(),w[i]=read(),tot+=w[i];
    DFS(c,c,c,0,tot-w[c],n-1);
    cout<<ans<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/hulean/p/10830572.html