luogu P2072 宗教问题 线性dp
#include<map> #include<queue> #include<time.h> #include<limits.h> #include<cmath> #include<ostream> #include<iterator> #include<set> #include<stack> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep_1(i,m,n) for(int i=m;i<=n;i++) #define mem(st) memset(st,0,sizeof st) inline int read() { int num=0, w=0; char ch=0; while (!isdigit(ch)) { w|=ch=='-'; ch = getchar(); } while (isdigit(ch)) { num = (num<<3) + (num<<1) + (ch^48); ch = getchar(); } return w? -num: num; } typedef long long ll; typedef pair<int,int> pii; typedef unsigned long long ull; typedef pair<double,double> pdd; const int inf = 0x3f3f3f3f; int n,m,k; int a[1010],f[1010],dp[1010],vis[1010]; int sum[1010][1010]; //sum[i][j]表示从i到j的不同的宗教个数 void solve() { memset(f,127,sizeof f); memset(dp,127,sizeof dp); cin>>n>>m>>k; for(int i=1; i<=n; i++) cin>>a[i]; for(int i=1; i<=n; i++) { memset(vis,0,sizeof vis); for(int j=i; j<=n; j++) { sum[i][j]=sum[i][j-1]; if(!vis[a[j]]) sum[i][j]++,vis[a[j]]=1; } } f[0]=0;//前i个人至少分为f[i]个集体 f[1]=1; for(int i=2; i<=n; i++) for(int j=i; j>=1; j--) if(sum[i-j+1][i]<=k) f[i]=min(f[i],f[i-j]+1); dp[0]=0; dp[1]=1; for(int i=2; i<=n; i++) for(int j=i; j>=1; j--) if(sum[i-j+1][i]<=k) dp[i]=min(dp[i],dp[i-j]+sum[i-j+1][i]); cout<<f[n]<<endl<<dp[n]<<endl; } int main() { int t=1; while(t--) solve(); return 0; }