洛谷 P1220 關路燈

2022-08-17 07:15:12 字數 1850 閱讀 5956

先附上我最開始的想法 記憶化搜尋

#include#include

#include

#include

using

namespace

std;

intn,m,i,ans;

int sum1[55],sum2[55],s[55],p[55

];int jiyi[55][55][2

];int dp(int a,int b,int

z)else

else

else

}else

else

}else

else}}

}}

return

fanhui;

}int

main()

sum1[

0]=0

; sum1[n+1]=0

;

for(i=1;i<=n;i++)

for(i=n;i>=1;i--)

ans=dp(m,m,0

); cout

}

這個程式本身是可以執行的 但是時間複雜度不允許,在洛谷資料中tle了5個點

#include#include

#include

#include

using

namespace

std;

int n,m,v[55],ans=0x7fffffff

;struct

stya[

55];

//當前位置,已經關了的點,當前時間,當前總耗電,當前沒關的燈的總功率。

int min(int a,int

b)void dfs(int now,int num,int t,int sum,int

su)

for(int i=1;i<=n;++i)

}for(int i=-1;i>=-n;--i)

if(now+i>=1&&!v[now+i])

}int

main()

v[m]=1

; dfs(m,

0,0,0

,su);

cout

return0;

}

這一套是經過剪枝後的記憶化搜尋,

第一次加的判定是if(sum>ans)return ;這個很好理解,就是當前耗電大於答案,剪掉。

第二次是if(sum+(當前已用的時間)*(當前沒關的燈的總功率)>ans)return ;

但仍然考試中tle五個點= =

然而這題的正統方法是區間dp

先附上ac**:

#include #include 

using

namespace

std;

const

int maxm=60

;int

a[maxm],b[maxm],sum[maxm],n,m,c;

int f[maxm][maxm][2

];int min(int a,int

bint max(int a,int

b)int

main()

int ans=min(f[1][n][0],f[1][n][1

]); printf("%d

",ans);

return0;

}

其中f【i】【j】【0/1】是指當前關閉i-j的燈並且站在了i(三維數是0)或j(三維數是1)

因為資料範圍很和諧,所以三維輕鬆ac

自定義min max是因為害怕會因為這一點點的時間而tle

洛谷 P1220 關路燈

某一村莊在一條路線上安裝了n盞路燈,每盞燈的功率有大有小 即同一段時間內消耗的電量有多有少 老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節省電...

洛谷 P1220 關路燈

某一村莊在一條路線上安裝了n盞路燈,每盞燈的功率有大有小 即同一段時間內消耗的電量有多有少 老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節省電...

洛谷 P1220 關路燈

原本想用搜尋先超時一把 然後發現剪枝居然過了 include include include include include include using namespace std int d 10005 記錄燈的功率 int lef,righ,minx int run int x,int y 記錄...