• dp


    我一般是不做dp题目的,但是这一个dp我必须要纪念一下,这是我做的为数不多的dp

    因为我从这个dp里面学到了一个新技能----------列出所有情况,找规律写转移方程
    之前我都是硬看,但是看不出来<哭>

    以下内容学自这个博客

    问题 A: Concerts
    时间限制: 1 Sec  内存限制: 128 MB
    提交: 314  解决: 74
    [提交] [状态] [命题人:admin]
    题目描述
    John enjoys listening to several bands, which we shall denote using A through Z. He wants to attend several concerts, so he sets out to learn their schedule for the upcoming season. 
    He finds that in each of the following n days (1 ≤ n ≤ 105), there is exactly one concert. He decides to show up at exactly k concerts (1 ≤ k ≤ 300), in a given order, and he may decide to attend more than one concert of the same band.
    However, some bands give more expensive concerts than others, so, after attending a concert given by band b, where b spans the letters A to Z, John decides to stay at home for at least hb days before attending any other concert.
    Help John figure out how many ways are there in which he can schedule his attendance, in the desired order. Since this number can be very large, the result will be given modulo 109 + 7.
    
    输入
    The first line contains k and n. The second line contains the 26 hb values, separated by spaces.
    The third line contains the sequence of k bands whose concerts John wants to attend e.g.,AFJAZ, meaning A, then F etc. The fourth line contains the schedule for the following n days,specified in an identical manner.
    
    输出
    The number of ways in which he can schedule his attendance (mod 109 + 7).
    
    样例输入
    复制样例数据
    2 10
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    AB
    ABBBBABBBB
    样例输出
    10
    

    题目大意:字符串只由AZ组成,给定s字符串长度k(k<=300),p字符串长度是n(<=1e5),再给定字母AZ匹配成功后需要间隔的次数a[27],再给出字符串s, p。求s匹配p的方案数

    dp[i][j]:匹配到i位置时已经匹配了j个的方案数。
    (1) s[j]==p[i]:dp[i][j] = dp[i-1][j] + dp[i-a[id]-1][j-1];
    (2) s[j]!=p[i]:dp[i][j] = dp[i-1][j];

    在这里插入图片描述

    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int mod = 1e9 + 7 ;
    int dp[100010][310] ;
    int a[27];
    char s[100010] , p[100010] ;
    int main()
    {
    	int k , n ;
    	scanf("%d%d",&k,&n) ;
    	for(int i = 1;i <= 26 ;i ++)
    	 scanf("%d",&a[i]) ;
    	scanf("%s",s + 1) ;
    	scanf("%s",p + 1) ;
    	for(int i = 1;i <= n;i ++)
    	 {
    	 	dp[i][1] = dp[i - 1][1] ;
    	 	if(s[1] == p[i]) dp[i][1] ++ ;
    	 }
    	 for(int i = 1;i <= n;i ++)
    	  for(int j = 2;j <= k;j ++)
    	   {
    	   	dp[i][j] = dp[i - 1][j] ;
    	   	if(s[j] == p[i]) 
    	   	{
    	   		 int id = s[j - 1] - 'A' + 1;
    	   		 if(i - a[id] - 1 < 1) continue ;
    	   		 dp[i][j] = (dp[i][j] + dp[i - a[id] - 1][j - 1]) % mod ;
    	   	
    		}
    	   	
    	   }
    	   cout << dp[n][k] << endl ;
    	   return 0 ;
    }
    
    
    每次做题提醒自己:题目到底有没有读懂,有没有分析彻底、算法够不够贪心、暴力够不够优雅。
  • 相关阅读:
    Win7 配置Android开发环境 狼人:
    Windows Phone 7 Tips (3) 狼人:
    Windows Phone 7 Tips (1) 狼人:
    探索移动Web网页编码设计 狼人:
    初探AIR for Android开发 狼人:
    Android设计趋势分析10则 狼人:
    Android与服务器端数据交互 狼人:
    Android UI基本测验:线性布局 狼人:
    Android用户界面设计:线性布局 狼人:
    Eclipse开发Android应用程序入门:重装上阵 狼人:
  • 原文地址:https://www.cnblogs.com/spnooyseed/p/12870926.html
Copyright © 2020-2023  润新知