質問の意味:あり、残りの3つの状態が、あるイベントAを行い、イベントBを行い、同じ日に両方のイベントを行うことができない、あなたは残りの日数の最小数のための手配を行うことができるか尋ねてください。毎日は、それがすべてを行うことも行うことができ、あるいは1つまたは唯一の残りの部分を行うことができます |
動的なプログラミングのアイデア:
あなたは物事の現在の操作を行うことができれば実際には、明らかに影状態の転送のこの質問は、その後、現在の最適なソリューションは、現在選択されて、最適なソリューションの以前の最小値と異なっている必要があります。
現在のイベントはAを行うなど、その最適解の最小値が最適解と残りのイベントBの最適なソリューション前日行うことです。その
DP [I] [1] =分(DP [I-1] [0]、DP [I-1] [2])。
他の州の場合はそれも理由です。
最後の答えは、ライン上の最小選ぶその最終日に3つの州です。
実際には、この問題とこの問題の一番上のボタンを強制するには、私は何ができるのかに興味を持っているこのブログを見て、金型です。
#include <iostream>
#include <vector>
#include <cstdio>
#include <map>
#include <climits>
#include <string>
#include <cmath>
#include <cstring>
#include <algorithm>
#define maxn 105
using namespace std;
typedef long long ll;
static int inf = 0x3f3f3f3f;
int main()
{
int n;
cin>>n;
int a[105];
for(int i=1; i<=n; i++)
cin>>a[i];
vector<vector<int>> dp(105,vector<int>(3,inf));
dp[0][0]=0;
dp[0][1]=0;
dp[0][2]=0;//能做的事情无非三种
for(int i=1; i<=n; i++)
{
if(a[i]==0) //当前状态只能为0时,找出前面做0、做1,做2的最优解
{
dp[i][0]=min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))+1;
}
if(a[i]==1) //当前状态可以选择0或2时,找出对应之前的最优解
{
dp[i][0]=min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))+1; //当前
dp[i][2]=min(dp[i-1][0],dp[i-1][1]);
}
if(a[i]==2)
{
dp[i][0]=min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))+1;
dp[i][1]=min(dp[i-1][0],dp[i-1][2]);
}
if(a[i]==3)
{
dp[i][0]=min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))+1;
dp[i][2]=min(dp[i-1][0],dp[i-1][1]);
dp[i][1]=min(dp[i-1][0],dp[i-1][2]);
}
}
int minone=inf;
for(int i=0;i<=3;i++)//最后一天在三种状态里面挑最小
minone=min(minone,dp[n][i]);
cout<<minone<<endl;
return 0;
}