10分求助,思路有点怪
查看原帖
10分求助,思路有点怪
775202
lxw_zmltb楼主2024/12/3 20:01

第一问没有问题,就是第二问; 我设他f[i][j]f[i][j]代表最后一个区域长这样:i,i+1,i+2...,ji,i+1, i+2 ...,j

可得转移方程为

i=ji=j 就是新建一个区域,那就是结尾为j-1的最小值了

f[i][j]=f[1i1][j1]的最大值+1f[i][j]=f[1到i-1][j-1]的最大值+1

i!=ji !=j 那就是继承从上一个,那就是从ii开始j1j-1结束的,如果在iij1j-1这个区间有新加入的这个数也就是a[j]a[j]那就为f[i1][j1]f[i-1][j-1],如果没有,那就是f[i1][j1+1]f[i-1][j-1+1]

#include<bits/stdc++.h>
using namespace std;
const int maxa=1e6;
int n,m,K,a[1010],f[1010][1010],qwq[30],ansa=1; 
void ans1(){
	int l=1;
	for(int i=1;i<=n;i++){
		int t=0;
		for(int j=l;j<=i;j++){
			if(qwq[a[j]]==0)t++;
			qwq[a[j]]=1;
		}
		if(t>K){
			l=i;
			ansa++;
		}
		for(int k=1;k<=25;k++)qwq[k]=0;
	}
	cout<<ansa<<endl;
}
int main(){
	cin>>n>>m>>K;
	for(int i=1;i<=n;i++)
		cin>>a[i];
		ans1();
	for(int i=1;i<=n;i++)
		f[i][i]=INT_MAX;
	f[1][1]=1;
	for(int j=2;j<=n;j++){
		for(int i=1;i<=j;i++){
			if(i==j)
				for(int k=1;k<=i-1;k++)
					f[i][j]=min(f[i][j],f[k][j-1]+1);
			else{
				if(f[i][j-1]==maxa){
					f[i][j]=f[i][j-1];
					continue;
				}
				bool bb=true;
				for(int k=i;k<=j-1;k++){
					if(a[k]==a[j]){
						f[i][j]=f[i][j-1];
						bb=false;
						break;
					}
				}
				if(bb==false)continue;
				f[i][j]=f[i][j-1]+1;
				int t=0;
				for(int k=i;k<=j;k++){
					qwq[k]++;
					if(qwq[k]==1)t++;
				}
				for(int k=1;k<=25;k++)qwq[k]=0;
				if(t>K)f[i][j]=maxa;
			}
		}
	}
	int ans=INT_MAX;
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++){
//			cout<<f[i][j]<<' ';
//		}cout<<endl;
//	}
	for(int i=1;i<=n;i++)ans=min(ans,f[i][n]);
	cout<<ans;
	return 0;
}/*
10 4 3
1 2 3 4 3 4 3 2 1 2
*/

我感觉思路没问题,加了点减枝时间肯定够但WA了只有10分,大佬们帮帮我

2024/12/3 20:01
加载中...