滑雪
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
int dp[110][110],a[110][110];
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
int m,n;
int dfs(int x,int y){
if(dp[x][y]>=0) return dp[x][y];
int cnt=1;
for(int i=0;i<4;i++){
int nx = x+dx[i],ny = y+dy[i];
if(nx>=1 && nx<=m && ny>=1 && ny<=n && a[x][y]>a[nx][ny]){
cnt = max(dfs(nx,ny)+1,cnt);
}
}
dp[x][y] = cnt;
return dp[x][y];
}
int main(){
cin>>m>>n;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
scanf("%d",&a[i][j]);
}
}
memset(dp, -1, sizeof(dp));
int ans = 1;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
ans = max(ans,dfs(i, j));
}
}
printf("%d\n",ans);
return 0;
}
多段图最短路
(下面的代码并没有进行路径记录)
#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<queue>
#include<vector>
#define ms0(a) memset(a,0,sizeof(a))
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int inf = (1<<30)+1000;
int m,n,map[15][105],path[15][105],d[15][105];
int dfs(int x,int y)
{
if(d[x][y]<inf) return d[x][y];
if(y==n) return d[x][y]=map[x][y];
int op[] = {x,x-1,x+1};
if(x==1) op[1]=m;
if(x==m) op[2]=1;
int &res = d[x][y];
for(int k=0;k<3;k++)
{
int cost = map[x][y]+dfs(op[k],y+1);
res = min(cost,res);
}
return res;
}
int main(){
while(~scanf("%d%d",&m,&n))
{
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
scanf("%d",&map[i][j]);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
d[i][j] = inf;
int ans = inf;
for(int i=1;i<=m;i++)
ans = min(ans,dfs(i,1));
printf("%d\n",ans);
}
return 0;
}
两道题其实都是在DAG上求最长路(最短路的题目)
对比:
搜索起点:
一个是不确定的,一个是第一列。
搜索终点:
一个是仍是不确定的,一个是最后一列。
方案选择:
一个是上下左右,一个是右上,右,右下。
目标答案:
一个是全图求max,一个是第一列求最小值。
买可乐
买可乐时的方案就对应下面的五条if语句。
尤其是,用1个10元和3个一元买一个可乐,找1个5元的情况。
注意,题目不允许一次性买多个可乐。
if(c>=1) m=min(m,dfs(cnt+1, a+2, b, c-1)+1);
if(b>=2) m=min(m,dfs(cnt+1, a+2, b-2, c)+2);
if(b>=1&&a>=3) m=min(m,dfs(cnt+1, a-3, b-1, c)+4);
if(c>=1&&a>=3) m=min(m,dfs(cnt+1, a-3, b+1, c-1)+4);
if(a>=8) m=min(m,dfs(cnt+1,a-8,b,c)+8);
#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#define ms0(a) memset(a,0,sizeof(a))
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
int ncase,dp[1000][200][60],m,n1,n5,n10;;
int dfs(int cnt,int a,int b,int c){
if(dp[a][b][c]>0) return dp[a][b][c];
if(cnt==m) return dp[a][b][c]=0;
int m(INF);
if(c>=1) m=min(m,dfs(cnt+1, a+2, b, c-1)+1);
if(b>=2) m=min(m,dfs(cnt+1, a+2, b-2, c)+2);
if(b>=1&&a>=3) m=min(m,dfs(cnt+1, a-3, b-1, c)+4);
if(c>=1&&a>=3) m=min(m,dfs(cnt+1, a-3, b+1, c-1)+4);
if(a>=8) m=min(m,dfs(cnt+1,a-8,b,c)+8);
return dp[a][b][c]=m;
}
int main(){
cin>>ncase;
while(ncase--){
scanf("%d%d%d%d",&m,&n1,&n5,&n10);
memset(dp,-1,sizeof(dp));
printf("%d\n",dfs(0, n1, n5, n10));
}
return 0;
}