例如求:abcdefg中k的个数
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mst(s,_s) memset(s, _s, sizeof(s))
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const int N = 1e6+100;
int T,n,m;
int get_num(vector<int>nums,int l,int r)
{
int res=0;
for(int i=l;i>=r;i--)
res=res*10+nums[i];
return res;
}
int get10(int x)
{
int res=1;
while(x--)
{
res*=10;
}
return res;
}
// 1到n之间,有多少x
int dp(int n,int k)
{
if(!n) return 0;
vector<int>nums;
while(n){
nums.push_back(n%10);
n/=10;
}
int res=0;
/* abcxedg. 拿abc的大小shiu
0 - abc-1 x 000-999
abc
xk 000-999
当k=0
abc不能为0,否则0 +0 前导0
*/
n=nums.size();
for(int i=n-1-!k;i>=0;i--)
{
int x=nums[i];
if(i<n-1)
{
res+=get_num(nums,n-1,i+1)*get10(i);
if(k==0) res-=get10(i);
}
if(x>k) res+=get10(i);
else if(x==k) res+=1+get_num(nums,i-1,0);
}
return res;
}
int main() {
int l,r;
while(cin>>l>>r)
{
if(!l || !r) break;
if(l>r) swap(l,r);
for(int i=0;i<=9;i++)
cout<<dp(r,i)-dp(l-1,i)<<' ';
cout<<endl;
}
return 0;
}
树形DP f[u] [0] 表示u为根节点不选u的最大值,f[u] [1] 表示u为根节点选u的最大值
选u的话,各个子节点只能不选,不选u的话,子节点可选可不选
#include
#include
#include
using namespace std;
const int N = 6010;
int n;
int h[N], e[N], ne[N], idx;
int happy[N];
int f[N][2];
bool has_fa[N];
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
void dfs(int u)
{
f[u][1] = happy[u];
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
dfs(j);
f[u][1] += f[j][0];
f[u][0] += max(f[j][0], f[j][1]);
}
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) scanf("%d", &happy[i]);
memset(h, -1, sizeof h);
for (int i = 0; i < n - 1; i ++ )
{
int a, b;
scanf("%d%d", &a, &b);
add(b, a);
has_fa[a] = true;
}
int root = 1;
while (has_fa[root]) root ++ ;
dfs(root);
printf("%d\n", max(f[root][0], f[root][1]));
return 0;
}
一个二维矩阵,代表一个平面的高度,从高往低滑
问:最长的滑雪路径。
f[i] [j] 表示从这个点开始滑的最长距离
#include
#include
using namespace std;
const int N=1e3+100;
int f[N][N],h[N][N];
int n,m;
int dx[4]={
-1,0,1,0},dy[4]={
0,1,0,-1};
int dp(int a,int b)
{
if(f[a][b]!=-1) return f[a][b];
int maxv=1;
for(int i=0;i<4;i++)
{
/// cout<
int na=a+dx[i],nb=b+dy[i];
//cout<
if(na>=1 && na<=n && nb>=1 && nb<=m && h[na][nb] < h[a][b])
maxv = max(maxv,dp(na,nb)+1);
}
return f[a][b]=maxv;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>h[i][j];
int res=0;
memset(f,-1,sizeof f);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
// cout<
res=max(res,dp(i,j));
}
cout<<res<<endl;
return 0;
}
#include
#include
using namespace std;
const int N = 100010;
int n;
int a[N];
int q[N];
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
int len = 0;
for (int i = 0; i < n; i ++ )
{
int l = 0, r = len;
while (l < r)
{
int mid = l + r + 1 >> 1;
if (q[mid] < a[i]) l = mid;
else r = mid - 1;
}
len = max(len, r + 1);
q[r + 1] = a[i];
}
printf("%d\n", len);
return 0;
}