Niuke Zhou Zhou Lian Qi Rabbit's work (1) (3D dp optimization)

l i n k link link

Ideas:

We set three-dimensional dp: dp [i] [j] [k] dp[i][j][k]dp[i][j][k]到第 i i I have workedjjso farj day, includingjjI worked continuously in j dayskkThe minimum physical strength consumed in k days.

So how to transfer?
When the iiWhen you must rest on i day, that is,s[ i] = = 0 s[i]==0s[i]==0

  • d p [ i ] [ j ] [ 0 ] = = d p [ i − 1 ] [ j ] [ k ] dp[i][j][0] == dp[i-1][j][k] dp[i][j][0]==dp[i1][j][k](其中 1 < = k < = j 1<=k<=j 1<=k<=j);

This iiWhen there is rest or no rest for i days, that is,s[ i] = = 1 s[i]==1s[i]==1

  • 休息: d p [ i ] [ j ] [ 0 ] = d p [ i − 1 ] [ j ] [ k ] dp[i][j][0] = dp[i-1][j][k] dp[i][j][0]=dp[i1][j][k](其中 1 < = k < = j 1<=k<=j 1<=k<=j);
  • 不休息: d p [ i ] [ j ] [ k ] = m i n ( d p [ i ] [ j ] [ k ] , d p [ i − 1 ] [ j − 1 ] [ k − 1 ] + k ) dp[i][j][k] = min( dp[i][j][k] , dp[i-1][j-1][k-1]+k) dp[i][j][k]=min(dp[i][j][k],dp[i1][j1][k1]+k);

Because of the space limitation of this question, we have to compress the space. Using the compressed space idea of ​​01 backpack, we can remove the first dimension and let jjj can be traversed in reverse order, and the complexity iso (n ∗ n ∗ n) o(n*n*n)o ( nnn)

#include<bits/stdc++.h>
using namespace std;

const int maxn = 500,inf = 1e9+20;
int dp[maxn][maxn];
int main()
{
    
    
	int n,k;
	cin >> n >> k;
	string s;
	cin >> s;
	for(int i=0;i<=n+1;i++)
	for(int j=0;j<=n+1;j++)dp[i][j] = inf;
	dp[0][0] = 0;
	for(int i=1;i<=n;i++)
	{
    
    
		for(int j = i; j > 0; j--)
		{
    
    
			for(int k = 1; k <= j; k++)
			{
    
    
				if(s[i-1] == '0')dp[j][0] = min(dp[j][k],dp[j][0]);
				else
				{
    
    
					dp[j][0] = min(dp[j][0],dp[j][k]);
					dp[j][k] = min(dp[j][k] , dp[j-1][k-1] + k);
				}
			}
		}
	}
	for(int i=n;i>0;i--)
	for(int j=1;j<=n;j++)
	if(dp[i][j] <= k)
	{
    
    
		cout<<i<<'\n';
		return 0;
	}
	puts("0");
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_44499508/article/details/106231079