动规思路大赏
T1数字三角形
f[i][j]=max(f[i+1][j],f[i+1][j+1])+a[i][j];//其中i自下向上,因为上受下影响
T2过河卒
if((i!=1||j!=1)&&!vis[i][j]) step[i][j]=step[i-1][j]+step[i][j-1];
T3最长公共子序列(太坑了!!!1e5的范围,一开始是按n2做的,连MLE带TLE了4遍!!!)
T4木根加工
查看代码
//对于每个木棍,以长、宽为第一、第二关键字排序,DP交换宽度不合适的
#include<bits/stdc++.h>
using namespace std;
int ans=-1,n,dp[5010];
bool vis[100010];
struct node{ int l,w; }wod[100010];
bool cmp(node aa,node bb)
{
if(aa.l!=bb.l)return aa.l>bb.l;
return aa.w>bb.w;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>wod[i].l>>wod[i].w;
sort(wod+1,wod+n+1,cmp);
for(int i=2;i<=n;i++)
{
for(int j=1;j<i;j++)
{
if(wod[i].w>wod[j].w)
{
dp[i]=max(dp[j]+1,dp[i]);
}
}
ans=max(ans,dp[i]);
}
printf("%d",ans+1);
return 0;
}
T5尼克的任务(要是我是老板第一个开掉尼克)
很容易误认为是贪心,但有可能选了一个很短的任务,完成后不巧赶上一个时间非常长的-->所以需要动态规划
查看代码
for(int i=1;i<=k;i++)
{
cin>>a[i].p>>a[i].t;
sum[a[i].p]++;//该时间开始的事件
}
sort(a+1,a+k+1,cmp);
for(int i=n;i>=1;i--)
{
if(!sum[i])f[i]=f[i+1]+1;
else for(int j=1;j<=sum[i];j++)
{
f[i]=max(f[i+a[num].t],f[i]);//做或不做
num++;
}
}
printf("%d",f[1]);
T6宝物筛选