先附上我最開始的想法 記憶化搜尋
#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 #includeusing
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 記錄...