A - Ancient Civilization
题意:略。
题解:
统计每一个位置的0、1数量,选择大的那个即为最好的。
#include <bits/stdc++.h>
using namespace std;
#define sc scanf
#define pr printf
#define ll long long
const int maxn=1e3;
//int a[maxn],vis[100];
int a[35],b[35];
int main() {
int t;cin>>t;
while(t--){
ll n,m,x;
cin>>n>>m;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
while(n--){
cin>>x;
int now=0;
while(x){
if(x%2==0) a[now++]++;
else b[now++]++;
x/=2;
}
for(int i=now;i<m;i++)a[i]++;//别忘了这个,在这里wa了
}
ll k=1;
ll sum=0;
for(int i=0;i<35;i++){
if(b[i]>a[i])sum+=k;
k*=2;
}
cout<<sum<<endl;
}
return 0;
}
B. Elementary Particles
题意:
找到最长相同长度子段,使其满足存在相同位置的值相等。
题解:
对于每次找到相同的值,可以得到字段的最长长度为,相对较前的前面所有数可以计入,相对较后的后面所有数需要计入,还有该位置+1。
对每次出现相同的进行计算,记录最大值。
借助了a数组进行记录,每次循环都需要清楚原本留下的数值,所以复杂度为O(n·m),大概是1e9的级别,2s足够处理。
#include <bits/stdc++.h>
using namespace std;
#define sc scanf
#define pr printf
#define ll long long
const int maxn=1e5+5e4+3;
//int a[maxn],vis[100];
int a[maxn];
int main() {
int t;cin>>t;
while(t--){
int n;cin>>n;
int x; int mmax=INT_MIN;
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++){
cin>>x;
if(a[x]!=0)mmax=max(mmax,a[x]+n-i);
a[x]=i;
}
if(mmax==INT_MIN)pr("-1\n");
else pr("%d\n",mmax);
}
return 0;
}
C. Road Optimization
题意:
给出n个节点。
从i出发的速度按i处的值算。
d记录位置,a记录允许速度。
要求求出最多删去k个节点的全程最小长度。
题解:
o(n3)的dp[i][j],i指当前位置,j指余下了多少节点。
状态转移方程:
dp[i][k]=min(dp[i][k],dp[j][k-1]+a[j]*(d[i]-d[j]));
具体请结合代码注释理解。
注意
dp[1][0]=0——起点不能删去,其它为无穷大
d[n+1]=l——终点为l。
还是有点没弄明白贪心的不对,局部最优不代表全部最优?但是暂时想象不出来反例。
#include <bits/stdc++.h>
using namespace std;
#define sc scanf
#define pr printf
#define ll long long
const int maxn=1e3;
//int a[maxn],vis[100];
int a[maxn],d[maxn];
int dp[maxn][maxn];
int main() {
int n,l,k0;cin>>n>>l>>k0;
for(int i=1;i<=n;i++)cin>>d[i];
for(int i=1;i<=n;i++)cin>>a[i];
d[n+1]=l;
for(int i=0;i<=n+1;i++)
for(int j=0;j<=n+1;j++)dp[i][j]=1e9;
dp[1][0]=0;
for(int i=1;i<=n+1;i++)//第i个
for(int j=1;j<i;j++)//从j到i位置除去
for(int k=1;k<=j;k++)//保留了k个
dp[i][k]=min(dp[i][k],dp[j][k-1]+a[j]*(d[i]-d[j]));
int ans=1e9;
for(int i=0;i<=k0;i++)//找出删去的最小值,即查找保留的为:n-
//i
ans=min(ans,dp[n+1][n-i]);
pr("%d\n",ans);
return 0;
}