Codeforces#302-C. Writing Code-DP/滚动数组

http://codeforces.com/contest/544/problem/C

题意:

给你n,m,k,mod,表示有n个程序员,要求写m行代码,代码的bugs不超过k个,求方案数模mod

接下来是一个n个数的数组,表示第i个程序员写一行代码会有tm[i]个 bugs   【被黑得好凄凉的感觉....】

n,m,k都是 【1,500】;

如果你选了X个程序员,你只需要保证一共写了m行代码,可以有y个人完全不写....

思路:

dp解决...主要是就转移方程有点麻烦..

dp[ i ][ j ][ k ]表示前i个程序员写了j行代码且bug不超过k


对其dp[ i ][ j ][ k ]分两种情况讨论,

1】 第i个程序员一行代码都没写

2】第i个程序员至少写了1行


情况1】,如果第i个程序员一行都不写,显然就是前i-1个人写完了所有代码,也就是dp[ i ][ j ][ k ]=dp[ i-1 ][ j ][ k ]种  

情况2】,如果第i个程序员至少写了1行,我们怎么表示呢

难道是这样??     int sum=0;

for (line =1;line<= j;line ++)

{

sum+=dp[ i-1 ] [ j-line ] [ k-line*a[ i ]  ];

}

 

显然如果这样,dp就是O(n^4),显然不行....

我们再看看 以前计算得到的结果是否能被利用:

我们可以发现dp[ i ] [ j-1 ] [ k-a[i] ] 是在dp[ i ][ j ][ k ]之前已经计算过了的,

其意义是前i个程序员里面 一共写了j-1行代码,得到的bugs是k-a[i],隐藏意思就是(这个方案里,第i个程序员可能写过的代码行数为 【0,j-1】)

显然,对于dp[ i ] [ j-1 ] [ k-a[i] ] 下的每一种方案得到的代码,只要再加上一行第i 个程序员写的代码,那么行数就会变为J,bugs数就变为k,而第i个程序员写过的代码

行数就从【0,j-1】变为【1,j】,也就是 情况2】  【第i个程序员至少写了1行】,所以dp[ i ] [ j-1 ] [ k-a[i] ] 就是该情况下的方案数

-------------------------------------------------------------------------------------
从而我们得到了转移方程 dp[ i ] [ j-1 ] [ k-a[i] ]=dp[ i-1 ][ j ][ k ]  +  dp[ i ] [ j-1 ] [ k-a[i] ]  ;

显然开三位数组爆内存啦。。注意到状态方程的 【i】 只用到了i,i-1,那么我们可以用滚动数组,或者直接不用也行了。。
上述方程就转化为了  dp[j][k]=(dp[j][k]+dp[j-1][k-tm[i]]);  // 第一个dp[j][k]是指dp[i][j][k],第二个dp[j][k]由于尚未更新,其实是上一次的结果 也就是dp[i-1][j][k],第三个j-1已经更新过了,所以就是dp[i]的j-1

 

 //未优化空间方程 
for (i=1;i<=n;i++)
		for (j=1;j<=m;j++)
			for (k=0;k<=b;k++)
				if (k>=tm[i])
	dp[i][j][k]= (dp[i-1][j][k]+dp[i][j-1][k-tm[i]])%mod;
				else
					dp[i][j][k]=dp[i-1][j][k]; 


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;

int dp[505][505];
int tm[505];
int main()
{
	
	int n,m,b,mod;
	int k,i,j;
	scanf("%d%d%d%d",&n,&m,&b,&mod);
	for (i=1;i<=n;i++)
	{
		scanf("%d",&tm[i]);
	}
	//sort(tm+1,tm+1+n); 
	
 	dp[0][0]=1;
	for (i=1;i<=n;i++)
	{
		for (j=1;j<=m;j++)
		{
			for (k=tm[i];k<=b;k++)
			{
				 
				
				dp[j][k]=(dp[j][k]+dp[j-1][k-tm[i]])%mod;
				
			}
		}
	}
	
	int sum=0;
	for (i=0;i<=b;i++)
	sum=(sum+dp[m][i])%mod; 

		printf("%d\n" ,sum);
	
	return 0;
	
}



 //未优化空间方程 <pre class="source prettyprint" style="margin-top: 0px; margin-bottom: 0px; padding: 2px; font-size: 13.2px; border: 1px solid rgb(136, 136, 136); background-color: rgb(255, 255, 255);"><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln">i</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln">i</span><span class="pun" style="color: rgb(102, 102, 0);"><=</span><span class="pln">n</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln">i</span><span class="pun" style="color: rgb(102, 102, 0);">++)</span><span class="pln">
		</span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln">j</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln">j</span><span class="pun" style="color: rgb(102, 102, 0);"><=</span><span class="pln">m</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln">j</span><span class="pun" style="color: rgb(102, 102, 0);">++)</span><span class="pln">
			</span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln">k</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln">k</span><span class="pun" style="color: rgb(102, 102, 0);"><=</span><span class="pln">b</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln">k</span><span class="pun" style="color: rgb(102, 102, 0);">++)</span><span class="pln">
				</span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln">k</span><span class="pun" style="color: rgb(102, 102, 0);">>=</span><span class="pln">tm</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">i</span><span class="pun" style="color: rgb(102, 102, 0);">])</span><span class="pln">
	dp</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">i</span><span class="pun" style="color: rgb(102, 102, 0);">][</span><span class="pln">j</span><span class="pun" style="color: rgb(102, 102, 0);">][</span><span class="pln">k</span><span class="pun" style="color: rgb(102, 102, 0);">]=</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln">dp</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">i</span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">][</span><span class="pln">j</span><span class="pun" style="color: rgb(102, 102, 0);">][</span><span class="pln">k</span><span class="pun" style="color: rgb(102, 102, 0);">]+</span><span class="pln">dp</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">i</span><span class="pun" style="color: rgb(102, 102, 0);">][</span><span class="pln">j</span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">][</span><span class="pln">k</span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln">tm</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">i</span><span class="pun" style="color: rgb(102, 102, 0);">]])%</span><span class="pln">mod</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln">
				</span><span class="kwd" style="color: rgb(0, 0, 136);">else</span><span class="pln">
					dp</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">i</span><span class="pun" style="color: rgb(102, 102, 0);">][</span><span class="pln">j</span><span class="pun" style="color: rgb(102, 102, 0);">][</span><span class="pln">k</span><span class="pun" style="color: rgb(102, 102, 0);">]=</span><span class="pln">dp</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln">i</span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">][</span><span class="pln">j</span><span class="pun" style="color: rgb(102, 102, 0);">][</span><span class="pln">k</span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln"> </span>
 
 

你可能感兴趣的:(Codeforces#302-C. Writing Code-DP/滚动数组)