题目来源:https://codeforces.com/contest/1307
这场还好没打
这题就是个简单的贪心,尽量让靠近左边的先往左移
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const int sz=18;
const double eps=1e-10;
const double pi=acos(-1);
int n,m;
char str[N];
int f[N];
map<string,int> mm;
vector<string> v;
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
int t;
r(t);
while(t--){
r(n); r(m);
LL ans=0;
FOR(i,1,n){
int a; r(a);
if(m>=(i-1)*a){
ans+=a;
m-=(i-1)*a;
}
else{
ans+=m/(i-1);
m=m%(i-1);
}
}
cout<<ans<<endl;
}
return 0;
}
这题只要线段的和大于x 那么一定是可以到达的,你让他随便弯曲总有方法到达
至于为什么不会选择多种线段组合,可以这样想 假如由两种组成a、b,且a>b
现在ka+b>=x 那(k+1)a>x也成立 所以没必要考虑
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const int sz=18;
const double eps=1e-10;
const double pi=acos(-1);
int n,m;
char str[N];
int f[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
int t;
r(t);
while(t--){
r(n); r(m);
int ans=INF;
FOR(i,1,n){
int a;
r(a);
if(a>m){
ans=min(2,ans);
}
else{
int cnt=m/a;
if(m%a!=0) cnt++;
ans=min(ans,cnt);
}
}
cout<<ans<<endl;
}
return 0;
}
显而易见,最大的一定是出现在长度为1或2之中,因为如果长度为3,在这个长度里面一定会找到长度为2的。例 abc 有k次 那 ab起码有k次 所以最大只需要在长度为1和2的里面找 组合有26+26*26种 取其中的最大值即可
怎么统计呢?统计每个字母的贡献
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const int sz=18;
const double eps=1e-10;
const double pi=acos(-1);
int n,m;
char str[N];
LL sum[N][30];
LL res[30][30];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
scanf("%s",str+1);
n=strlen(str+1);
FOR(i,1,n){
int t=str[i]-'a'+1;
FOR(j,1,26){
if(j==t) sum[i][j]=sum[i-1][j]+1;
else sum[i][j]=sum[i-1][j];
//cout<
}
//cout<
}
LL ans=0;
FOR(i,1,n){
int t=str[i]-'a'+1;
FOR(j,1,26){
res[t][j]+=sum[n][j]-sum[i][j];
}
}
FOR(i,1,26){
ans=max(ans,sum[n][i]);
FOR(j,1,26){
ans=max(ans,res[i][j]);
}
}
cout<<ans<<endl;
return 0;
}
首先我们求出所有点到1 和 n的最短距离 即为fst lst
设两个特殊点a,b 假如现在连接了a b 那么会产生两个1 - n的距离 ,那个人肯定要走最近的 即 m i n ( f s t a + l s t b , f s t b + l s t a ) + 1 min(fsta+lstb,fstb+lsta)+1 min(fsta+lstb,fstb+lsta)+1 但是这个不太好求 我们转换一下 m i n ( f s t a − l s t a , f s t b − l s t b ) + l s t a + l s t b + 1 min(fsta-lsta,fstb-lstb)+lsta+lstb+1 min(fsta−lsta,fstb−lstb)+lsta+lstb+1 我们对这些点按fsta-fstb从小到大排序,那假如我们现在选了其中的点y 和它前面的点x 那当前的答案就是 f s t x − l s t x + l s t x + l s t y + 1 = f s t x + l s t y + 1 fstx-lstx+lstx+lsty+1=fstx+lsty+1 fstx−lstx+lstx+lsty+1=fstx+lsty+1 lsty就是当前点的,而fstx当然要取前面最大的,所以排完序之后遍历的时候记录一个前缀最大值即可~
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rr(x,y) read(x);read(y)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
#define pb(x) push_back(x)
#define sss(str) scanf("%s",str+1)
#define ssf(x) scanf("%lf",&x)
#define all(x) x.begin(),x.end()
using namespace std;
typedef long long LL;
typedef double dd;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const int sz=18;
const double eps=1e-10;
const double pi=acos(-1);
//***********************
int fst[N],lst[N];
int f[N];
bool vis[N];
vector<int> v[N];
//***********************
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
void bfs(int x,int step)
{
memset(vis,0,sizeof vis);
queue<pt> q;
q.push(mp(x,1));
bool flag=(x==1);
while(q.size()){
pt now=q.front(); q.pop();
vis[now.first]=1;
if(flag) fst[now.first]=now.second;
else lst[now.first]=now.second;
for(auto y:v[now.first]){
if(!vis[y]) vis[y]=1,q.push(mp(y,now.second+1));
}
}
}
int main()
{
int n,m,k;
rrr(n,m,k);
FOR(i,1,k) r(f[i]);
FOR(i,1,m){
int a,b;
rr(a,b);
v[a].pb(b);
v[b].pb(a);
}
bfs(1,1);
bfs(n,1);
vector<pt> g;
FOR(i,1,k){
int x=f[i];
g.pb(mp(fst[x]-lst[x],x));
}
sort(all(g));
int ans=0;
int maxy=-INF;
for(auto x:g){
//cout<
ans=max(ans,maxy+lst[x.second]);
maxy=max(maxy,fst[x.second]);
//cout<
}
cout<<min(fst[n]-1,ans-1)<<endl;
return 0;
}