P17261 [ICPC 2017 Urumqi R] The Number Triangle 题解

闲话

关于我写这道题时样例输出缺少空格然后一直错这回事,别问我怎么知道还要输出空格的。

题目大意

有两个三角形,第一个全为正整数,第二个全为小写字母。第一个需要先求出从下往上的最大路径和,然后需要求有哪几个位置可以得到最大路径和。但是需要按路径上对应的小写字母组成的字典序最小的字符串的字典序升序排序,然后输出对应的索引。

算法思路

首先求得最大路径和,然后转移时顺便求出目前字典序最小的字符串,然后注意记录字典序最小的字符串的数组要降维,最后按照字典序排序输出就行了。

#include<bits/stdc++.h>
using namespace std;
const int N=1505;
int a[N][N],dp[N][N];
char ch[N][N];//小写字母三角形
string ans[2][N];//记录字典序最小的字符串,滚动数组
struct node{
  string str;int id;
}anss[N];
bool cmp(node x,node y){
  if(x.str==y.str)return x.id<y.id;
  return x.str<y.str;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	int T;cin>>T;
  while(T--){
    int n;cin>>n;
    for(int i=1;i<=n;i++){
      ans[0][i]=ans[1][i]="";//初始化
      for(int j=1;j<=i;j++){
        cin>>a[i][j]>>ch[i][j];
        dp[i][j]=-1e9;
      }
    }
    dp[1][1]=a[1][1],ans[1][1]=ch[1][1];//初始化
    for(int i=2;i<=n;i++){
      for(int j=1;j<=i;j++){
        ans[i&1][j]=ch[i][j];//初始值
        dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+a[i][j];//动态转移
        if(dp[i-1][j]>dp[i-1][j-1]){
          ans[i&1][j]+=ans[(i&1)^1][j];//这样是更快的
        }else if(dp[i-1][j]<dp[i-1][j-1]){
          ans[i&1][j]+=ans[(i&1)^1][j-1];
        }else if(ans[(i&1)^1][j]<ans[(i&1)^1][j-1]){//这里如果两个一样就比较字典序
          ans[i&1][j]+=ans[(i&1)^1][j];
        }else{
          ans[i&1][j]+=ans[(i&1)^1][j-1];
        }
      }
    }
    int mx=0,m=0;
    for(int i=1;i<=n;i++)mx=max(mx,dp[n][i]);
    for(int i=1;i<=n;i++){
      if(dp[n][i]!=mx)continue;
      anss[++m]={ans[n&1][i],i};//注意不要写成ans[1][i]或ans[0][i]
    }
    sort(anss+1,anss+1+m,cmp);
    for(int i=1;i<=m;i++)cout<<anss[i].id<<" ";
    cout<<'\n';
  }
}
posted @ 2026-10-17 18:53  SCX2014  阅读(2)  评论(0)    收藏  举报