(1)对于每一个位置,有三种选择,一是选择删除,二是选择当排头清洗,三是被前面的排头清洗;
(2)注意到总是要求将最后一位数清洗完,即前面信息依赖后面信息,于是考虑从后往前分析,令f[i]描述i~n最小代价,则对于第i位,可选择
- #include
- #include
- using namespace std;
- const int maxn = 2e5 + 10;
- int dp[maxn], a[maxn];
-
- void solve() {
- int n;
-
- cin >> n;
-
- for (int i = 1; i <= n; ++i) {
- cin >> a[i];
- }
- dp[n] = 1;
- dp[n+1] = 0;
- for (int i = n - 1; i >= 1; --i) {
- dp[i] = 1 + dp[i+1]; // 删除第i个
- if (i + a[i] <= n) { // 利用第i个做为区间起点
- dp[i] = min(dp[i], dp[i+a[i]+1]);
- }
- }
-
- printf("%d\n", dp[1]);
- }
- int main()
- {
- int t;
- cin >> t;
- while(t --)
- {
- solve();
- }
-
-
- return 0;
- }