1. 判断括号字符串有效
给定一个只包括 '(',')','{','}','[',']' 的字符串 s(1 <= s.length <= 1e4) ,
判断字符串是否有效。如果有效,输出有效括号的个数。如果无效,则输出False。
简单的栈
int main() {
int t;
cin>>t;
char match[3][2] = {{'(',')'},{'[',']'},{'{','}'}};
while(t--){
string cur;
cin>>cur;
stack<int> st;
bool flag = true;
int res = 0;
for(auto c:cur){
bool corr = false;
for(int i=0;i<3;i++){
if(c==match[i][1]){//如果匹配的是后面的右括号
if(!st.empty()&&st.top()==match[i][0]){
st.pop();
corr = true;
res++;
}
else{
flag = false;
break;
}
}
}
if(!corr) st.push(c);//没有抵消掉,入栈
}
if(st.empty()&&flag) cout<<res<<endl;
else cout<<"False"<<endl;
}
return 0;
}
2. 滑雪
Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。
Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。
记忆化搜索
int main() {
int R,C;
cin>>R>>C;
vector<vector<int>> grid(R,vector<int>(C));
for(int i=0;i<R;i++)
for(int j=0;j<C;j++)
cin>>grid[i][j];
vector<vector<int>> dp(R,vector<int>(C));//dp[x][y]表示以x,y为起点的最长路径长度
int dir[4][2] = {{1,0},{0,-1},{-1,0},{0,1}};
function<int(int,int)> f = [&](int x,int y)->int{
if(dp[x][y]!=0) return dp[x][y];
int res = 0;
for(int i=0;i<4;i++){
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if(nx<0||ny<0||nx==R||ny==C) continue;
if(grid[nx][ny]<=grid[x][y]) continue;
res = max(res,f(nx,ny));
}
dp[x][y] = res + 1;
return dp[x][y];
};
int res = 0;
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
res = max(res,f(i,j));
}
}
cout<<res;
return 0;
}
3. 挖宝藏
一个人有n体力,m个金币,k个宝藏点,p条双向路径。每个宝藏点都需要一定的金币v才能挖掘获取价值w。
每次通过一条路径都需要花费t的体力,可以走重复路径,但是宝藏只能获取一次。你可以选择任意一个点作为起点,问最多能获得多少价值的宝藏。
题意不清楚,数据也有问题,乱写的代码
int main() {
int n,m,k,p;//持有体力,持有金币,点数目,路径数目
cin>>n>>m>>k>>p;
vector<vector<int>> treasure(21,vector<int>(2));//价值和需要的金币
vector<vector<int>> graph(21,vector<int>(21,INT_MAX/3));//花费体力的代价
for(int i=0;i<k;i++)
cin>>treasure[i][0]>>treasure[i][1];
for(int i=0;i<p;i++){
int from,to,fee;
cout<<"开始读取行"<<endl;
cin>>from>>to>>fee;
graph[from][to] = min(graph[from][to],fee);
graph[to][from] = min(graph[to][from],fee);
}
cout<<"读取完毕"<<endl;
for(int kk=0;kk<k;kk++)//弗洛伊德遍历中转点
for(int i=0;i<k;i++)
for(int j=0;j<k;j++)
graph[i][j] = min(graph[i][j],graph[i][kk]+graph[kk][j]);
cout<<"弗洛伊德计算完毕"<<endl;
//dp[i][j][k][state]表示以i为起点,剩余体力为j,剩余金币为k,已经挖取点状态为state的最大宝藏价值获取量
vector<vector<int>> dp(k+1,vector<int>(1<<(k+1),-1));
function<int(int,int,int,int)> f = [&](int x,int state,int sum1,int sum2)->int{
cout<<"遍历"<<x<<"点"<<endl;
if(dp[x][state]!=-1) return dp[x][state];
int res = 0;
for(int i=0;i<k;i++){//遍历所有点
if(!(state&(1<<i))){//第i个点没有挖掘
if((sum1+graph[x][i]<=n)&&(sum2+treasure[i][1]<=m)){//体力和金币都满足要求
res = max(res,f(i,state|(1<<i),sum1+graph[x][i],sum2+treasure[i][1])+treasure[i][0]);
}
}
}
dp[x][state] = res;
return res;
};
cout<<f(0,0,0,0)<<endl;
return 0;
}
标签:23,快手,graph,2024.08,cin,int,vector,宝藏,dp
From: https://www.cnblogs.com/929code/p/18403164