A(map用法):
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int n, k, temp;
cin >> n >> k;
map<int, int> cnt;
for(int i=0; i<n; i++)
{
cin >> temp;
cnt[temp]++;
}
int goods;
int bads;
int ans;
ans = goods = bads = 0;
map<int,int>::iterator it;
for(it=cnt.begin();it!=cnt.end();it++)
{
bads += it->second % 2;
goods += it->second/2 * 2;
}
int pp=(n+1-goods)/2;
if(pp>bads)
ans=goods+bads;
else
ans=goods+pp;
cout << ans << endl;
return 0;
}
B(模拟题):
代码:
#include <stdio.h>
#include <cmath>
int main()
{
long long int n, k, i;
scanf("%lld %lld", &n, &k);
for (i = 1; i <= n; ++i)
{
if (((i * (i + 1) / 2) - (n - i)) == k)
{
break;
}
}
printf("%lld\n", n - i);
return 0;
}
C:
题意:给你两行数,每行数代表一个队的成员身高,现从这两个队中挑选队员组成一个篮球队,要求不能从同一行中选择连续的两个成员,选出的成员身高必须不大于前一个选出的队员身高。
思路:
dp思路:max(该行上一个状态+另一行当前成员身高,该行上一个状态)
dp方程: dp[0][i]=max(dp[1][i-1]+a[i],dp[0][i-1])
dp[1][i]=max(dp[0][i-1]+b[i],dp[1][i-1])
一维线性dp,注意状态转移方程,0是取第一行,1是取第二行
代码:
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1000000;
typedef long long ll;
int n;
ll a[maxn];
ll b[maxn];
ll dp[2][1000005];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
cin>>b[i];
}
dp[0][0]=0;
dp[1][0]=0;
for(int i=1;i<=n;i++){
dp[0][i]=max(a[i]+dp[1][i-1],dp[0][i-1]);//第一行开始取
dp[1][i]=max(b[i]+dp[0][i-1],dp[1][i-1]);//第二行开始取
}
cout<<max(dp[0][n],dp[1][n])<<endl;
return 0;
}