#include<bits/stdc++.h>
using namespace std;
int a[110];
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{ int x,c=0,maxv=-1;memset(a,0,sizeof a);
for(int i=1;i<=n;i++){
scanf("%d",&x);if(a[x]==0) c++;//种类数
a[x]++;maxv=max(maxv,a[x]);//最大值
}
int v=maxv/m,ans=0;//至少有多少份
if(maxv%m) v++;//v++
ans=v*c*m-n;
printf("%d\n",ans);
}
}
给你一片文章,让你把每个字符放在一个ab的网格中,每一个位置可以是或者字符,要求为行数不超过5,列数不超过20,每相邻两行之间的*数量不能超过1.求满足条件的矩阵中行数最少的,行数相同取列最少的
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const int N= 1e5+5;
int n,sz,cnum,rnum,last;
string s;
bool p;
int main(){
cin>>s;
n= s.size();//printf("%d\n",n);
cnum= (n/20)+(!!(n%20));//行
rnum= (n/cnum)+(!!(n%cnum));//列
cout<<cnum<<" "<<rnum<<'\n';
for(int i=0;i<cnum;i++){
if((n%cnum) && (n%cnum)==i){
rnum--;//
// printf("%d\n",rnum);
p=1;
}
for(int j=last;j<last+rnum;j++)
cout<<s[j];
last+=rnum;
if(p)
cout<<'*';//补芯
cout<<'\n';
}
return 0;
}
贪心:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int a[maxn],b[maxn],n;
int main()
{
scanf("%d",&n);
a[n]=maxn;
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
b[0]= a[0]<a[1]?1:(a[0]==a[1]?3:5);/// 贪心第一个为1,3,5
for(int i=1; i<n; i++)
{
if(a[i]==a[i-1]) {
if(a[i]==a[i+1]) //中间 取中间数
b[i] = b[i-1]!=3?3:2;///上一个不是3那就贪3,否则4和2都可以
else if(a[i]<a[i+1])
b[i] = b[i-1]!=1?1:2;///明显是一个谷底,贪最小的
else if(a[i]>a[i+1])///山头,贪最大
b[i] = b[i-1]!=5?5:4;
}
else if(a[i]>a[i-1])
b[i] = (a[i]>a[i+1]&&b[i-1]!=5)?5:b[i-1]+1;
///如果是山头并且没到顶(5),那就贪5,不然两种情况,
///一种是递增(a[i]<=a[i+1])的那就贪花费少,也就是+1
///另一种是山头到顶,一样+1变6被排除
else
b[i] = (a[i]<a[i+1]&&b[i-1]!=1)?1:b[i-1]-1;///同上,谷底
if(b[i]<1||b[i]>5) ///超出范围
{
printf("-1\n");
return 0;
}
}
for(int i=0; i<n; i++)
printf("%d ",b[i]);
return 0;
}
dp:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a,x) memset(a,x,sizeof(a))
#define se second
#define fi first
const ll mod=1e9+7;
const int INF= 0x3f3f3f3f;
const int N=1e5+5;
int n,a[N];
int dp[N][6];//第i个位置的值为k是否可行
int ans[N];
int pre[N][6];//记录每个第i个位置上可取的值
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=5;i++)
dp[1][i]=1;//第一位的取值
for(int i=1;i<n;i++)//由第一位递推
{
for(int j=1,k;j<=5;j++)//下一位 取值是否可行
{
if(dp[i][j]==0) continue;//状态不可行
if( a[i] < a[i+1] )
{
for( k=j+1;k<=5;k++)//i+1 位的可取值
{
dp[i+1][k]=1;
pre[i+1][k]=j;//记录i位的取值
}
}
else if( a[i] > a[i+1] )
{
for(int k=1;k<=j-1;k++)
{
dp[i+1][k]=1;
pre[i+1][k]=j;
}
}
else
{
for(int k=1;k<=5;k++)
{
if(j==k) continue;//不可以相同
dp[i+1][k]=1;
pre[i+1][k]=j;
}
}
}
}
int flag=0;
int u;
for(int i=1;i<=5;i++)
{
if(dp[n][i])
{
u=i;
for(int j=n;j>=1;j--)
{
ans[j]=u;//逆推 记录答案
u=pre[j][u];
}
flag=1; break;
}
}
if(!flag)
cout<<-1<<endl;
else
{
for(int i=1;i<=n;i++)
cout<<ans[i]<<' ';
}
}